Path: blob/main_old/src/tests/egl_tests/EGLPreRotationTest.cpp
1693 views
//1// Copyright 2020 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//5// EGLPreRotationTest:6// Tests pertaining to Android pre-rotation.7//89#include <gtest/gtest.h>1011#include <vector>1213#include "common/Color.h"14#include "common/platform.h"15#include "test_utils/ANGLETest.h"16#include "test_utils/gl_raii.h"17#include "util/EGLWindow.h"18#include "util/OSWindow.h"19#include "util/Timer.h"20#include "util/test_utils.h"2122using namespace angle;2324namespace25{2627using EGLPreRotationSurfaceTestParams = std::tuple<angle::PlatformParameters, bool>;2829std::string PrintToStringParamName(30const ::testing::TestParamInfo<EGLPreRotationSurfaceTestParams> &info)31{32std::stringstream ss;33ss << std::get<0>(info.param);34if (std::get<1>(info.param))35{36ss << "__PreRotationEnabled";37}38else39{40ss << "__PreRotationDisabled";41}42return ss.str();43}4445// A class to test various Android pre-rotation cases. In order to make it easier to debug test46// failures, the initial window size is 256x256, and each pixel will have a unique and predictable47// value. The red channel will increment with the x axis, and the green channel will increment48// with the y axis. The four corners will have the following values:49//50// Where GLES Render & ReadPixels coords Color (in Hex)51// Lower-left, which is (-1.0,-1.0) & ( 0, 0) in GLES will be black (0x00, 0x00, 0x00, 0xFF)52// Lower-right, which is ( 1.0,-1.0) & (256, 0) in GLES will be red (0xFF, 0x00, 0x00, 0xFF)53// Upper-left, which is (-1.0, 1.0) & ( 0, 256) in GLES will be green (0x00, 0xFF, 0x00, 0xFF)54// Upper-right, which is ( 1.0, 1.0) & (256, 256) in GLES will be yellow (0xFF, 0xFF, 0x00, 0xFF)55class EGLPreRotationSurfaceTest : public ANGLETestWithParam<EGLPreRotationSurfaceTestParams>56{57protected:58EGLPreRotationSurfaceTest()59: mDisplay(EGL_NO_DISPLAY),60mWindowSurface(EGL_NO_SURFACE),61mContext(EGL_NO_CONTEXT),62mOSWindow(nullptr),63mSize(256)64{}6566// Release any resources created in the test body67void testTearDown() override68{69if (mDisplay != EGL_NO_DISPLAY)70{71eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);7273if (mWindowSurface != EGL_NO_SURFACE)74{75eglDestroySurface(mDisplay, mWindowSurface);76mWindowSurface = EGL_NO_SURFACE;77}7879if (mContext != EGL_NO_CONTEXT)80{81eglDestroyContext(mDisplay, mContext);82mContext = EGL_NO_CONTEXT;83}8485eglTerminate(mDisplay);86mDisplay = EGL_NO_DISPLAY;87}8889mOSWindow->destroy();90OSWindow::Delete(&mOSWindow);9192ASSERT_TRUE(mWindowSurface == EGL_NO_SURFACE && mContext == EGL_NO_CONTEXT);93}9495void testSetUp() override96{97mOSWindow = OSWindow::New();98mOSWindow->initialize("EGLSurfaceTest", mSize, mSize);99}100101void initializeDisplay()102{103const angle::PlatformParameters platform = ::testing::get<0>(GetParam());104GLenum platformType = platform.getRenderer();105GLenum deviceType = platform.getDeviceType();106107std::vector<const char *> enabledFeatures;108std::vector<const char *> disabledFeatures;109if (::testing::get<1>(GetParam()))110{111enabledFeatures.push_back("enablePreRotateSurfaces");112}113else114{115disabledFeatures.push_back("enablePreRotateSurfaces");116}117enabledFeatures.push_back(nullptr);118disabledFeatures.push_back(nullptr);119120std::vector<EGLAttrib> displayAttributes;121displayAttributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);122displayAttributes.push_back(platformType);123displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE);124displayAttributes.push_back(EGL_DONT_CARE);125displayAttributes.push_back(EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE);126displayAttributes.push_back(EGL_DONT_CARE);127displayAttributes.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);128displayAttributes.push_back(deviceType);129displayAttributes.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);130displayAttributes.push_back(reinterpret_cast<EGLAttrib>(enabledFeatures.data()));131displayAttributes.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);132displayAttributes.push_back(reinterpret_cast<EGLAttrib>(disabledFeatures.data()));133displayAttributes.push_back(EGL_NONE);134135mDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,136reinterpret_cast<void *>(mOSWindow->getNativeDisplay()),137displayAttributes.data());138ASSERT_TRUE(mDisplay != EGL_NO_DISPLAY);139140EGLint majorVersion, minorVersion;141ASSERT_TRUE(eglInitialize(mDisplay, &majorVersion, &minorVersion) == EGL_TRUE);142143eglBindAPI(EGL_OPENGL_ES_API);144ASSERT_EGL_SUCCESS();145}146147void initializeContext()148{149EGLint contextAttibutes[] = {EGL_CONTEXT_CLIENT_VERSION,150::testing::get<0>(GetParam()).majorVersion, EGL_NONE};151152mContext = eglCreateContext(mDisplay, mConfig, nullptr, contextAttibutes);153ASSERT_EGL_SUCCESS();154}155156void initializeSurfaceWithRGBA8888Config()157{158const EGLint configAttributes[] = {159EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,160EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};161162EGLint configCount;163EGLConfig config;164ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) ||165(configCount != 1) == EGL_TRUE);166167mConfig = config;168169EGLint surfaceType = EGL_NONE;170eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);171172std::vector<EGLint> windowAttributes;173windowAttributes.push_back(EGL_NONE);174175if (surfaceType & EGL_WINDOW_BIT)176{177// Create first window surface178mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),179windowAttributes.data());180ASSERT_EGL_SUCCESS();181}182183initializeContext();184}185186void initializeSurfaceWithRGBA8888d24s8Config()187{188const EGLint configAttributes[] = {189EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8,190EGL_DEPTH_SIZE, 24, EGL_STENCIL_SIZE, 8, EGL_SAMPLE_BUFFERS, 0, EGL_NONE};191192EGLint configCount;193EGLConfig config;194ASSERT_TRUE(eglChooseConfig(mDisplay, configAttributes, &config, 1, &configCount) ||195(configCount != 1) == EGL_TRUE);196197mConfig = config;198199EGLint surfaceType = EGL_NONE;200eglGetConfigAttrib(mDisplay, mConfig, EGL_SURFACE_TYPE, &surfaceType);201202std::vector<EGLint> windowAttributes;203windowAttributes.push_back(EGL_NONE);204205if (surfaceType & EGL_WINDOW_BIT)206{207// Create first window surface208mWindowSurface = eglCreateWindowSurface(mDisplay, mConfig, mOSWindow->getNativeWindow(),209windowAttributes.data());210ASSERT_EGL_SUCCESS();211}212213initializeContext();214}215216void testDrawingAndReadPixels()217{218glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);219EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);220EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);221EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);222EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor::yellow);223ASSERT_GL_NO_ERROR();224225eglSwapBuffers(mDisplay, mWindowSurface);226ASSERT_EGL_SUCCESS();227228glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);229EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);230EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);231EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);232EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor::yellow);233ASSERT_GL_NO_ERROR();234235{236// Now, test a 4x4 area in the center of the window, which should tell us if a non-1x1237// ReadPixels is oriented correctly for the device's orientation:238GLint xOffset = 126;239GLint yOffset = 126;240GLsizei width = 4;241GLsizei height = 4;242std::vector<GLColor> pixels(width * height);243glReadPixels(xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);244EXPECT_GL_NO_ERROR();245// Expect that all red values equate to x and green values equate to y246for (int y = 0; y < height; y++)247{248for (int x = 0; x < width; x++)249{250int index = (y * width) + x;251GLColor expectedPixel(xOffset + x, yOffset + y, 0, 255);252GLColor actualPixel = pixels[index];253EXPECT_EQ(expectedPixel, actualPixel);254}255}256}257258{259// Now, test a 8x4 area off-the-center of the window, just to make sure that works too:260GLint xOffset = 13;261GLint yOffset = 26;262GLsizei width = 8;263GLsizei height = 4;264std::vector<GLColor> pixels2(width * height);265glReadPixels(xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels2[0]);266EXPECT_GL_NO_ERROR();267// Expect that all red values equate to x and green values equate to y268for (int y = 0; y < height; y++)269{270for (int x = 0; x < width; x++)271{272int index = (y * width) + x;273GLColor expectedPixel(xOffset + x, yOffset + y, 0, 255);274GLColor actualPixel = pixels2[index];275EXPECT_EQ(expectedPixel, actualPixel);276}277}278}279280eglSwapBuffers(mDisplay, mWindowSurface);281ASSERT_EGL_SUCCESS();282}283284EGLDisplay mDisplay;285EGLSurface mWindowSurface;286EGLContext mContext;287EGLConfig mConfig;288OSWindow *mOSWindow;289int mSize;290};291292// Provide a predictable pattern for testing pre-rotation293TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDraw)294{295// http://anglebug.com/4453296ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());297298// Flaky on Linux SwANGLE http://anglebug.com/4453299ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());300301// To aid in debugging, we want this window visible302setWindowVisible(mOSWindow, true);303304initializeDisplay();305initializeSurfaceWithRGBA8888Config();306307eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);308ASSERT_EGL_SUCCESS();309310// Init program311constexpr char kVS[] =312"attribute vec2 position;\n"313"attribute vec2 redGreen;\n"314"varying vec2 v_data;\n"315"void main() {\n"316" gl_Position = vec4(position, 0, 1);\n"317" v_data = redGreen;\n"318"}";319320constexpr char kFS[] =321"varying highp vec2 v_data;\n"322"void main() {\n"323" gl_FragColor = vec4(v_data, 0, 1);\n"324"}";325326ANGLE_GL_PROGRAM(program, kVS, kFS);327glUseProgram(program);328329GLint positionLocation = glGetAttribLocation(program, "position");330ASSERT_NE(-1, positionLocation);331332GLint redGreenLocation = glGetAttribLocation(program, "redGreen");333ASSERT_NE(-1, redGreenLocation);334335GLBuffer indexBuffer;336GLVertexArray vertexArray;337GLBuffer vertexBuffers[2];338339glBindVertexArray(vertexArray);340341std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};342glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);343glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],344GL_STATIC_DRAW);345346std::vector<GLfloat> positionData = {// quad vertices347-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};348349glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);350glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],351GL_STATIC_DRAW);352glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);353glEnableVertexAttribArray(positionLocation);354355std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)3560.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};357358glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);359glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],360GL_STATIC_DRAW);361glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);362glEnableVertexAttribArray(redGreenLocation);363364ASSERT_GL_NO_ERROR();365366testDrawingAndReadPixels();367}368369// Use dFdx() and dFdy() and still provide a predictable pattern for testing pre-rotation370// In this case, the color values will be the following: (dFdx(v_data.x), dFdy(v_data.y), 0, 1).371// To help make this meaningful for pre-rotation, the derivatives will vary in the four corners of372// the window:373//374// +------------+------------+ +--------+--------+375// | ( 0, 219) | (239, 249) | | Green | Yellow |376// +------------+------------+ OR +--------+--------+377// | ( 0, 0) | (229, 0) | | Black | Red |378// +------------+------------+ +--------+--------+379TEST_P(EGLPreRotationSurfaceTest, OrientedWindowWithDerivativeDraw)380{381// http://anglebug.com/4453382ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());383384// Flaky on Linux SwANGLE http://anglebug.com/4453385ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());386387// To aid in debugging, we want this window visible388setWindowVisible(mOSWindow, true);389390initializeDisplay();391initializeSurfaceWithRGBA8888Config();392393eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);394ASSERT_EGL_SUCCESS();395396// Init program397constexpr char kVS[] =398"#version 300 es\n"399"in highp vec2 position;\n"400"in highp vec2 redGreen;\n"401"out highp vec2 v_data;\n"402"void main() {\n"403" gl_Position = vec4(position, 0, 1);\n"404" v_data = redGreen;\n"405"}";406407constexpr char kFS[] =408"#version 300 es\n"409"in highp vec2 v_data;\n"410"out highp vec4 FragColor;\n"411"void main() {\n"412" FragColor = vec4(dFdx(v_data.x), dFdy(v_data.y), 0, 1);\n"413"}";414415ANGLE_GL_PROGRAM(program, kVS, kFS);416glUseProgram(program);417418GLint positionLocation = glGetAttribLocation(program, "position");419ASSERT_NE(-1, positionLocation);420421GLint redGreenLocation = glGetAttribLocation(program, "redGreen");422ASSERT_NE(-1, redGreenLocation);423424GLBuffer indexBuffer;425GLVertexArray vertexArray;426GLBuffer vertexBuffers[2];427428glBindVertexArray(vertexArray);429430std::vector<GLushort> indices = {// 4 squares each made up of 6 vertices:431// 1st square, in the upper-left part of window4320, 1, 2, 2, 3, 0,433// 2nd square, in the upper-right part of window4344, 5, 6, 6, 7, 4,435// 3rd square, in the lower-left part of window4368, 9, 10, 10, 11, 8,437// 4th square, in the lower-right part of window43812, 13, 14, 14, 15, 12};439glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);440glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],441GL_STATIC_DRAW);442443std::vector<GLfloat> positionData = {// 4 squares each made up of quad vertices444// 1st square, in the upper-left part of window445-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,446// 2nd square, in the upper-right part of window4470.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,448// 3rd square, in the lower-left part of window449-1.0f, 0.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f,450// 4th square, in the lower-right part of window4510.0f, 0.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f};452453glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);454glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],455GL_STATIC_DRAW);456glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);457glEnableVertexAttribArray(positionLocation);458459std::vector<GLfloat> redGreenData = {// green(0,110), black(0,0), red(115,0), yellow(120,125)460// 4 squares each made up of 4 pairs of half-color values:461// 1st square, in the upper-left part of window4620.0f, 110.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 110.0f,463// 2nd square, in the upper-right part of window4640.0f, 125.0f, 0.0f, 0.0f, 120.0f, 0.0f, 120.0f, 125.0f,465// 3rd square, in the lower-left part of window4660.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,467// 4th square, in the lower-right part of window4680.0f, 0.0f, 0.0f, 0.0f, 115.0f, 0.0f, 115.0f, 0.0f};469470glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);471glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],472GL_STATIC_DRAW);473glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);474glEnableVertexAttribArray(redGreenLocation);475476ASSERT_GL_NO_ERROR();477478// Draw and check the 4 corner pixels, to ensure we're getting the expected "colors"479glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);480GLColor expectedPixelLowerLeft(0, 0, 0, 255);481GLColor expectedPixelLowerRight(229, 0, 0, 255);482GLColor expectedPixelUpperLeft(0, 219, 0, 255);483GLColor expectedPixelUpperRight(239, 249, 0, 255);484EXPECT_PIXEL_COLOR_EQ(0, 0, expectedPixelLowerLeft);485EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, expectedPixelLowerRight);486EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, expectedPixelUpperLeft);487EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, expectedPixelUpperRight);488ASSERT_GL_NO_ERROR();489490// Make the image visible491eglSwapBuffers(mDisplay, mWindowSurface);492ASSERT_EGL_SUCCESS();493494// Draw again and check the 4 center pixels, to ensure we're getting the expected "colors"495glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, nullptr);496EXPECT_PIXEL_COLOR_EQ((mSize / 2) - 1, (mSize / 2) - 1, expectedPixelLowerLeft);497EXPECT_PIXEL_COLOR_EQ((mSize / 2) - 1, (mSize / 2), expectedPixelUpperLeft);498EXPECT_PIXEL_COLOR_EQ((mSize / 2), (mSize / 2) - 1, expectedPixelLowerRight);499EXPECT_PIXEL_COLOR_EQ((mSize / 2), (mSize / 2), expectedPixelUpperRight);500ASSERT_GL_NO_ERROR();501}502503// Android-specific test that changes a window's rotation, which requires ContextVk::syncState() to504// handle the new rotation505TEST_P(EGLPreRotationSurfaceTest, ChangeRotationWithDraw)506{507// This test uses functionality that is only available on Android508ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());509510// To aid in debugging, we want this window visible511setWindowVisible(mOSWindow, true);512513initializeDisplay();514initializeSurfaceWithRGBA8888Config();515516eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);517ASSERT_EGL_SUCCESS();518519// Init program520constexpr char kVS[] =521"attribute vec2 position;\n"522"attribute vec2 redGreen;\n"523"varying vec2 v_data;\n"524"void main() {\n"525" gl_Position = vec4(position, 0, 1);\n"526" v_data = redGreen;\n"527"}";528529constexpr char kFS[] =530"varying highp vec2 v_data;\n"531"void main() {\n"532" gl_FragColor = vec4(v_data, 0, 1);\n"533"}";534535ANGLE_GL_PROGRAM(program, kVS, kFS);536glUseProgram(program);537538GLint positionLocation = glGetAttribLocation(program, "position");539ASSERT_NE(-1, positionLocation);540541GLint redGreenLocation = glGetAttribLocation(program, "redGreen");542ASSERT_NE(-1, redGreenLocation);543544GLBuffer indexBuffer;545GLVertexArray vertexArray;546GLBuffer vertexBuffers[2];547548glBindVertexArray(vertexArray);549550std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};551glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);552glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],553GL_STATIC_DRAW);554555std::vector<GLfloat> positionData = {// quad vertices556-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};557558glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);559glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],560GL_STATIC_DRAW);561glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);562glEnableVertexAttribArray(positionLocation);563564std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)5650.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};566567glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);568glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],569GL_STATIC_DRAW);570glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);571glEnableVertexAttribArray(redGreenLocation);572573ASSERT_GL_NO_ERROR();574575// Change the rotation back and forth between landscape and portrait, and make sure that the576// drawing and reading happen consistently with the desired rotation.577// Last rotation needs to be portrait, since other tests expect it to be the default.578for (int i = 0; i < 4; i++)579{580bool landscape;581EGLint actualWidth = 0;582EGLint actualHeight = 0;583EGLint desiredWidth = 0;584EGLint desiredHeight = 0;585if ((i % 2) == 0)586{587landscape = true;588desiredWidth = 300;589desiredHeight = 200;590}591else592{593landscape = false;594desiredWidth = 200;595desiredHeight = 300;596}597mOSWindow->resize(desiredWidth, desiredHeight);598// setOrientation() uses a reverse-JNI call, which sends data to other parts of Android.599// Sometime later (i.e. asynchronously), the window is updated. Sleep a little here, and600// then allow for multiple eglSwapBuffers calls to eventually see the new rotation.601mOSWindow->setOrientation(desiredWidth, desiredHeight);602angle::Sleep(1000);603eglSwapBuffers(mDisplay, mWindowSurface);604ASSERT_EGL_SUCCESS();605606while ((actualWidth != desiredWidth) && (actualHeight != desiredHeight))607{608glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);609EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);610if (landscape)611{612EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor::red);613}614else615{616EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor::green);617}618ASSERT_GL_NO_ERROR();619620eglSwapBuffers(mDisplay, mWindowSurface);621ASSERT_EGL_SUCCESS();622623eglQuerySurface(mDisplay, mWindowSurface, EGL_HEIGHT, &actualHeight);624eglQuerySurface(mDisplay, mWindowSurface, EGL_WIDTH, &actualWidth);625}626}627}628629// A slight variation of EGLPreRotationSurfaceTest, where the initial window size is 400x300, yet630// the drawing is still 256x256. In addition, gl_FragCoord is used in a "clever" way, as the color631// of the 256x256 drawing area, which reproduces an interesting pre-rotation case from the632// following dEQP tests:633//634// - dEQP.GLES31/functional_texture_multisample_samples_*_sample_position635//636// This will test the rotation of gl_FragCoord, as well as the viewport, scissor, and rendering637// area calculations, especially when the Android device is rotated.638class EGLPreRotationLargeSurfaceTest : public EGLPreRotationSurfaceTest639{640protected:641EGLPreRotationLargeSurfaceTest() : mSize(256) {}642643void testSetUp() override644{645mOSWindow = OSWindow::New();646mOSWindow->initialize("EGLSurfaceTest", 400, 300);647}648649int mSize;650};651652// Provide a predictable pattern for testing pre-rotation653TEST_P(EGLPreRotationLargeSurfaceTest, OrientedWindowWithFragCoordDraw)654{655// http://anglebug.com/4453656ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());657658// Flaky on Linux SwANGLE http://anglebug.com/4453659ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());660661// To aid in debugging, we want this window visible662setWindowVisible(mOSWindow, true);663664initializeDisplay();665initializeSurfaceWithRGBA8888Config();666667eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);668ASSERT_EGL_SUCCESS();669670// Init program671constexpr char kVS[] =672"attribute vec2 position;\n"673"void main() {\n"674" gl_Position = vec4(position, 0, 1);\n"675"}";676677constexpr char kFS[] =678"void main() {\n"679" gl_FragColor = vec4(gl_FragCoord.x / 256.0, gl_FragCoord.y / 256.0, 0.0, 1.0);\n"680"}";681682ANGLE_GL_PROGRAM(program, kVS, kFS);683glUseProgram(program);684685GLint positionLocation = glGetAttribLocation(program, "position");686ASSERT_NE(-1, positionLocation);687688GLBuffer indexBuffer;689GLVertexArray vertexArray;690GLBuffer vertexBuffer;691692glBindVertexArray(vertexArray);693694std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};695glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);696glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],697GL_STATIC_DRAW);698699std::vector<GLfloat> positionData = {// quad vertices700-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};701702glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);703glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],704GL_STATIC_DRAW);705glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);706glEnableVertexAttribArray(positionLocation);707708ASSERT_GL_NO_ERROR();709710glViewport(0, 0, mSize, mSize);711712testDrawingAndReadPixels();713}714715// Pre-rotation tests for glBlitFramebuffer. A slight variation of EGLPreRotationLargeSurfaceTest,716// where the initial window size is still 400x300, and the drawing is still 256x256. In addition,717// glBlitFramebuffer is tested in a variety of ways. Separate tests are used to make debugging718// simpler, but they all share common setup. These tests reproduce interesting pre-rotation cases719// from dEQP tests such as the following:720//721// - dEQP.GLES3/functional_fbo_blit_default_framebuffer_*722// - dEQP.GLES3/functional_fbo_invalidate_*723constexpr GLuint kCoordMidWayShort = 127;724constexpr GLuint kCoordMidWayLong = 128;725constexpr GLColor kColorMidWayShortShort = GLColor(127, 127, 0, 255);726constexpr GLColor kColorMidWayShortLong = GLColor(127, 128, 0, 255);727constexpr GLColor kColorMidWayLongShort = GLColor(128, 127, 0, 255);728constexpr GLColor kColorMidWayLongLong = GLColor(128, 128, 0, 255);729// When scaling horizontally, the "black" and "green" colors have a 1 in the red component730constexpr GLColor kColorScaleHorizBlack = GLColor(1, 0, 0, 255);731constexpr GLColor kColorScaleHorizGreen = GLColor(1, 255, 0, 255);732// When scaling vertically, the "black" and "red" colors have a 1 in the green component733constexpr GLColor kColorScaleVertBlack = GLColor(0, 1, 0, 255);734constexpr GLColor kColorScaleVertRed = GLColor(255, 1, 0, 255);735736class EGLPreRotationBlitFramebufferTest : public EGLPreRotationLargeSurfaceTest737{738protected:739EGLPreRotationBlitFramebufferTest() {}740741GLuint createProgram()742{743constexpr char kVS[] =744"attribute vec2 position;\n"745"attribute vec2 redGreen;\n"746"varying vec2 v_data;\n"747"void main() {\n"748" gl_Position = vec4(position, 0, 1);\n"749" v_data = redGreen;\n"750"}";751752constexpr char kFS[] =753"varying highp vec2 v_data;\n"754"void main() {\n"755" gl_FragColor = vec4(v_data, 0, 1);\n"756"}";757758return CompileProgram(kVS, kFS);759}760761void initializeGeometry(GLuint program,762GLBuffer *indexBuffer,763GLVertexArray *vertexArray,764GLBuffer *vertexBuffers)765{766GLint positionLocation = glGetAttribLocation(program, "position");767ASSERT_NE(-1, positionLocation);768769GLint redGreenLocation = glGetAttribLocation(program, "redGreen");770ASSERT_NE(-1, redGreenLocation);771772glBindVertexArray(*vertexArray);773774std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};775glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);776glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],777GL_STATIC_DRAW);778779std::vector<GLfloat> positionData = {// quad vertices780-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};781782glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);783glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],784GL_STATIC_DRAW);785glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,786nullptr);787glEnableVertexAttribArray(positionLocation);788789std::vector<GLfloat> redGreenData = {// green(0,1), black(0,0), red(1,0), yellow(1,1)7900.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f};791792glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);793glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * redGreenData.size(), &redGreenData[0],794GL_STATIC_DRAW);795glVertexAttribPointer(redGreenLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,796nullptr);797glEnableVertexAttribArray(redGreenLocation);798}799800void initializeFBO(GLFramebuffer *framebuffer, GLTexture *texture)801{802glBindTexture(GL_TEXTURE_2D, *texture);803glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);804glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);805glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);806glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);807glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mSize, mSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,808nullptr);809810glBindFramebuffer(GL_FRAMEBUFFER, *framebuffer);811glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0);812}813814// Ensures that the correct colors are where they should be when the entire 256x256 pattern has815// been rendered or blitted to a location relative to an x and y offset.816void test256x256PredictablePattern(GLint xOffset, GLint yOffset)817{818EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, GLColor::black);819EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, GLColor::green);820EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, GLColor::red);821EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);822EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + kCoordMidWayShort,823kColorMidWayShortShort);824EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + kCoordMidWayLong,825kColorMidWayShortLong);826EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + kCoordMidWayShort,827kColorMidWayLongShort);828EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + kCoordMidWayLong,829kColorMidWayLongLong);830}831};832833// Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer834// to blit that pattern into various places within the 400x300 window835TEST_P(EGLPreRotationBlitFramebufferTest, BasicBlitFramebuffer)836{837// http://anglebug.com/4453838ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());839840// Flaky on Linux SwANGLE http://anglebug.com/4453841ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());842843// To aid in debugging, we want this window visible844setWindowVisible(mOSWindow, true);845846initializeDisplay();847initializeSurfaceWithRGBA8888Config();848849eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);850ASSERT_EGL_SUCCESS();851852// Init program853GLuint program = createProgram();854ASSERT_NE(0u, program);855glUseProgram(program);856857GLBuffer indexBuffer;858GLVertexArray vertexArray;859GLBuffer vertexBuffers[2];860initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);861ASSERT_GL_NO_ERROR();862863// Create a texture-backed FBO and render the predictable pattern to it864GLFramebuffer fbo;865GLTexture texture;866initializeFBO(&fbo, &texture);867ASSERT_GL_NO_ERROR();868869glViewport(0, 0, mSize, mSize);870glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);871ASSERT_GL_NO_ERROR();872873// Ensure the predictable pattern seems correct in the FBO874test256x256PredictablePattern(0, 0);875ASSERT_GL_NO_ERROR();876877//878// Test blitting the entire FBO image to a 256x256 part of the default framebuffer (no scaling)879//880881// Blit from the FBO to the default framebuffer (i.e. the swapchain)882glBindFramebuffer(GL_FRAMEBUFFER, 0);883glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);884glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);885glClearColor(0.0f, 0.0f, 0.0f, 1.0f);886glClear(GL_COLOR_BUFFER_BIT);887glBlitFramebuffer(0, 0, mSize, mSize, 0, 0, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);888ASSERT_GL_NO_ERROR();889890// Swap buffers to put the image in the window (so the test can be visually checked)891eglSwapBuffers(mDisplay, mWindowSurface);892ASSERT_GL_NO_ERROR();893894// Blit again to check the colors in the back buffer895glClear(GL_COLOR_BUFFER_BIT);896glBlitFramebuffer(0, 0, mSize, mSize, 0, 0, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);897glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);898test256x256PredictablePattern(0, 0);899ASSERT_GL_NO_ERROR();900901// Clear to black and blit to a different part of the window902glClear(GL_COLOR_BUFFER_BIT);903GLint xOffset = 40;904GLint yOffset = 30;905glViewport(xOffset, yOffset, mSize, mSize);906glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);907glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,908GL_COLOR_BUFFER_BIT, GL_NEAREST);909910// Swap buffers to put the image in the window (so the test can be visually checked)911eglSwapBuffers(mDisplay, mWindowSurface);912ASSERT_GL_NO_ERROR();913914// Blit again to check the colors in the back buffer915glClear(GL_COLOR_BUFFER_BIT);916glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,917GL_COLOR_BUFFER_BIT, GL_NEAREST);918glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);919test256x256PredictablePattern(xOffset, yOffset);920ASSERT_GL_NO_ERROR();921922ASSERT_EGL_SUCCESS();923}924925// Blit the ms0 stencil buffer to the default framebuffer with rotation on android.926TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithRotation)927{928// http://anglebug.com/4453929ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());930931// Flaky on Linux SwANGLE http://anglebug.com/4453932ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());933934setWindowVisible(mOSWindow, true);935936initializeDisplay();937initializeSurfaceWithRGBA8888d24s8Config();938939eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);940ASSERT_EGL_SUCCESS();941942mOSWindow->setOrientation(300, 400);943angle::Sleep(1000);944eglSwapBuffers(mDisplay, mWindowSurface);945ASSERT_EGL_SUCCESS();946947GLRenderbuffer colorbuf;948glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());949glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 64, 128);950951GLRenderbuffer depthstencilbuf;952glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());953glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_DEPTH24_STENCIL8, 64, 128);954955GLFramebuffer framebuffer;956glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());957glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);958glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,959depthstencilbuf);960glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,961depthstencilbuf);962glCheckFramebufferStatus(GL_FRAMEBUFFER);963964glClearColor(1.0f, 0.0f, 0.0f, 1.0f);965glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);966967// Replace stencil to 1.968ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());969glEnable(GL_STENCIL_TEST);970glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);971glStencilFunc(GL_ALWAYS, 1, 255);972drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);973974// Blit stencil buffer to default frambuffer.975GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};976glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);977glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);978glBlitFramebuffer(0, 0, 64, 128, 0, 0, 64, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,979GL_NEAREST);980glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);981982ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());983glDisable(GL_STENCIL_TEST);984drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);985986// Draw blue color if the stencil is equal to 1.987// If the blit finished successfully, the stencil test should all pass.988ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());989glEnable(GL_STENCIL_TEST);990glStencilFunc(GL_EQUAL, 1, 255);991drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f);992993// Check the result, especially the boundaries.994EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);995EXPECT_PIXEL_COLOR_EQ(32, 127, GLColor::blue);996EXPECT_PIXEL_COLOR_EQ(32, 0, GLColor::blue);997EXPECT_PIXEL_COLOR_EQ(63, 0, GLColor::blue);998EXPECT_PIXEL_COLOR_EQ(63, 64, GLColor::blue);999EXPECT_PIXEL_COLOR_EQ(32, 64, GLColor::blue);10001001// Some pixels around x=0/63 (related to the pre-rotation degree) still fail on android.1002// From the image in the window, the failures near one of the image's edge look like "aliasing".1003// We need to fix blit with pre-rotation. http://anglebug.com/50441004// EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);1005// EXPECT_PIXEL_COLOR_EQ(0, 64, GLColor::blue);1006// EXPECT_PIXEL_COLOR_EQ(63, 1, GLColor::blue);1007// EXPECT_PIXEL_COLOR_EQ(63, 127, GLColor::blue);10081009eglSwapBuffers(mDisplay, mWindowSurface);10101011ASSERT_GL_NO_ERROR();1012}10131014// Blit the multisample stencil buffer to the default framebuffer with rotation on android.1015TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleStencilWithRotation)1016{1017// http://anglebug.com/44531018ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());10191020// Flaky on Linux SwANGLE http://anglebug.com/44531021ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());10221023setWindowVisible(mOSWindow, true);10241025initializeDisplay();1026initializeSurfaceWithRGBA8888d24s8Config();10271028eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1029ASSERT_EGL_SUCCESS();10301031mOSWindow->setOrientation(300, 400);1032angle::Sleep(1000);1033eglSwapBuffers(mDisplay, mWindowSurface);1034ASSERT_EGL_SUCCESS();10351036GLRenderbuffer colorbuf;1037glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1038glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 64);10391040GLRenderbuffer depthstencilbuf;1041glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());1042glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 64);10431044GLFramebuffer framebuffer;1045glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1046glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);1047glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,1048depthstencilbuf);1049glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1050depthstencilbuf);1051glCheckFramebufferStatus(GL_FRAMEBUFFER);10521053glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1054glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);10551056// Replace stencil to 1.1057ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1058glEnable(GL_STENCIL_TEST);1059glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1060glStencilFunc(GL_ALWAYS, 1, 255);1061drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);10621063// Blit multisample stencil buffer to default frambuffer.1064GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};1065glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);1066glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1067glBlitFramebuffer(0, 0, 128, 64, 0, 0, 128, 64, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,1068GL_NEAREST);1069glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);10701071ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());1072glDisable(GL_STENCIL_TEST);1073drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);10741075// Draw blue color if the stencil is equal to 1.1076// If the blit finished successfully, the stencil test should all pass.1077ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());1078glEnable(GL_STENCIL_TEST);1079glStencilFunc(GL_EQUAL, 1, 255);1080drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.3f);10811082// Check the result, especially the boundaries.1083EXPECT_PIXEL_COLOR_EQ(127, 32, GLColor::blue);1084EXPECT_PIXEL_COLOR_EQ(64, 32, GLColor::blue);1085EXPECT_PIXEL_COLOR_EQ(0, 63, GLColor::blue);1086EXPECT_PIXEL_COLOR_EQ(64, 63, GLColor::blue);10871088// Some pixels around x=0/127 or y=0 (related to the pre-rotation degree)still fail on android.1089// We need to fix blit with pre-rotation. http://anglebug.com/50441090// Failures of Rotated90Degrees.1091// EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);1092// EXPECT_PIXEL_COLOR_EQ(127, 63, GLColor::blue);1093// Failures of Rotated180Degrees.1094// EXPECT_PIXEL_COLOR_EQ(64, 0, GLColor::blue);1095// EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);1096// Failures of Rotated270Degrees.1097// EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);1098// EXPECT_PIXEL_COLOR_EQ(0, 32, GLColor::blue);10991100eglSwapBuffers(mDisplay, mWindowSurface);11011102ASSERT_GL_NO_ERROR();1103}11041105// Blit stencil to default framebuffer with flip and prerotation.1106TEST_P(EGLPreRotationBlitFramebufferTest, BlitStencilWithFlip)1107{1108// http://anglebug.com/44531109ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());11101111// Flaky on Linux SwANGLE http://anglebug.com/44531112ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());11131114// We need to fix blit with pre-rotation. http://anglebug.com/50441115ANGLE_SKIP_TEST_IF(IsAndroid() || IsWindows());11161117// To aid in debugging, we want this window visible1118setWindowVisible(mOSWindow, true);11191120initializeDisplay();1121initializeSurfaceWithRGBA8888d24s8Config();11221123eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1124ASSERT_EGL_SUCCESS();11251126mOSWindow->setOrientation(300, 400);1127angle::Sleep(1000);1128eglSwapBuffers(mDisplay, mWindowSurface);1129ASSERT_EGL_SUCCESS();11301131constexpr int kSize = 128;1132glViewport(0, 0, kSize, kSize);11331134GLRenderbuffer colorbuf;1135glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1136glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);11371138GLRenderbuffer depthstencilbuf;1139glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());1140glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_DEPTH24_STENCIL8, kSize, kSize);11411142GLFramebuffer framebuffer;1143glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1144glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);1145glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,1146depthstencilbuf);1147glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1148depthstencilbuf);1149glCheckFramebufferStatus(GL_FRAMEBUFFER);11501151glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1152glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);11531154// Replace stencil to 1.1155ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1156glEnable(GL_STENCIL_TEST);1157glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1158glStencilFunc(GL_ALWAYS, 1, 255);1159drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);11601161// Blit stencil buffer to default frambuffer with X-flip.1162GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};1163glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);1164glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1165glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize,1166GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);1167glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);11681169ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());1170glDisable(GL_STENCIL_TEST);1171drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);11721173// Draw blue color if the stencil is equal to 1.1174// If the blit finished successfully, the stencil test should all pass.1175glEnable(GL_STENCIL_TEST);1176glStencilFunc(GL_EQUAL, 1, 255);1177ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),1178essl31_shaders::fs::RedGreenGradient());1179drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);11801181// Check the result, especially the boundaries.1182EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Black1183EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red1184EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green1185EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow11861187eglSwapBuffers(mDisplay, mWindowSurface);11881189ASSERT_GL_NO_ERROR();1190}11911192// Blit color buffer to default framebuffer with Y-flip/X-flip.1193TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorToDefault)1194{1195// This test uses functionality that is only available on Android1196ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());11971198// To aid in debugging, we want this window visible1199setWindowVisible(mOSWindow, true);12001201initializeDisplay();1202initializeSurfaceWithRGBA8888Config();12031204eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1205ASSERT_EGL_SUCCESS();12061207constexpr int kSize = 128;1208glViewport(0, 0, kSize, kSize);12091210GLRenderbuffer colorbuf;1211glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1212glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);12131214GLFramebuffer framebuffer;1215glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1216glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);12171218glCheckFramebufferStatus(GL_FRAMEBUFFER);12191220glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1221glClear(GL_COLOR_BUFFER_BIT);12221223ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),1224essl31_shaders::fs::RedGreenGradient());12251226EGLint desiredWidth = 300;1227EGLint desiredHeight = 400;1228mOSWindow->resize(desiredWidth, desiredHeight);1229mOSWindow->setOrientation(desiredWidth, desiredHeight);1230angle::Sleep(1000);1231eglSwapBuffers(mDisplay, mWindowSurface);1232ASSERT_EGL_SUCCESS();12331234glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());1235drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);12361237// Blit color buffer to default frambuffer without flip.1238glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1239glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1240glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);12411242// Check the result, especially the boundaries.1243EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck1244EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red1245EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green1246EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow12471248// Blit color buffer to default frambuffer with Y-flip.1249glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());1250glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1251glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);1252glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);12531254EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0); // Green1255EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0); // Yellow1256EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0); // Balck1257EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0); // Red12581259// Blit color buffer to default frambuffer with X-flip.1260glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());1261glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1262glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1263glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);12641265EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0); // Red1266EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0); // Balck1267EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow1268EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0); // Green12691270ASSERT_GL_NO_ERROR();1271}12721273// Blit color buffer from default framebuffer with Y-flip/X-flip.1274TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorFromDefault)1275{1276// This test uses functionality that is only available on Android1277ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());12781279// To aid in debugging, we want this window visible1280setWindowVisible(mOSWindow, true);12811282initializeDisplay();1283initializeSurfaceWithRGBA8888Config();12841285eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1286ASSERT_EGL_SUCCESS();12871288constexpr int kSize = 128;1289glViewport(0, 0, kSize, kSize);12901291GLRenderbuffer colorbuf;1292glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1293glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);12941295GLFramebuffer framebuffer;1296glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1297glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);1298glCheckFramebufferStatus(GL_FRAMEBUFFER);12991300glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1301glClear(GL_COLOR_BUFFER_BIT);13021303ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),1304essl31_shaders::fs::RedGreenGradient());13051306EGLint desiredWidth = 300;1307EGLint desiredHeight = 400;1308mOSWindow->resize(desiredWidth, desiredHeight);1309mOSWindow->setOrientation(desiredWidth, desiredHeight);1310angle::Sleep(1000);1311eglSwapBuffers(mDisplay, mWindowSurface);1312ASSERT_EGL_SUCCESS();13131314glBindFramebuffer(GL_FRAMEBUFFER, 0);1315drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);13161317// Blit color buffer from default frambuffer without flip.1318glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());1319glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1320glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());13211322// Check the result, especially the boundaries.1323EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck1324EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red1325EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green1326EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow13271328// Blit color buffer from default frambuffer with Y-flip.1329glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1330glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());1331glBlitFramebuffer(0, 0, kSize, kSize, 0, kSize, kSize, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);1332glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());13331334EXPECT_PIXEL_NEAR(0, 0, 0, 253, 0, 255, 1.0); // Green1335EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 253, 0, 255, 1.0); // Yellow1336EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 0, 0, 255, 1.0); // Balck1337EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 0, 0, 255, 1.0); // Red13381339// Blit color buffer from default frambuffer with X-flip.1340glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1341glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.get());1342glBlitFramebuffer(0, 0, kSize, kSize, kSize, 0, 0, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1343glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());13441345EXPECT_PIXEL_NEAR(0, 0, 253, 0, 0, 255, 1.0); // Red1346EXPECT_PIXEL_NEAR(kSize - 1, 0, 0, 0, 0, 255, 1.0); // Balck1347EXPECT_PIXEL_NEAR(0, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow1348EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 0, 253, 0, 255, 1.0); // Green13491350ASSERT_GL_NO_ERROR();1351}13521353// Blit multisample color buffer to resolved framebuffer.1354TEST_P(EGLPreRotationBlitFramebufferTest, BlitMultisampleColorToResolved)1355{1356// This test uses functionality that is only available on Android1357ANGLE_SKIP_TEST_IF(isVulkanRenderer() && !IsAndroid());13581359// To aid in debugging, we want this window visible1360setWindowVisible(mOSWindow, true);13611362initializeDisplay();1363initializeSurfaceWithRGBA8888Config();13641365eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1366ASSERT_EGL_SUCCESS();13671368constexpr int kSize = 128;1369glViewport(0, 0, kSize, kSize);13701371GLRenderbuffer colorMS;1372glBindRenderbuffer(GL_RENDERBUFFER, colorMS.get());1373glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize, kSize);13741375GLRenderbuffer colorResolved;1376glBindRenderbuffer(GL_RENDERBUFFER, colorResolved.get());1377glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);13781379GLFramebuffer framebufferMS;1380glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS.get());1381glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);13821383glCheckFramebufferStatus(GL_FRAMEBUFFER);13841385glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1386glClear(GL_COLOR_BUFFER_BIT);13871388ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),1389essl31_shaders::fs::RedGreenGradient());1390drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);13911392GLFramebuffer framebufferResolved;1393glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());1394glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,1395colorResolved.get());13961397EGLint desiredWidth = 300;1398EGLint desiredHeight = 400;1399mOSWindow->resize(desiredWidth, desiredHeight);1400mOSWindow->setOrientation(desiredWidth, desiredHeight);1401angle::Sleep(1000);1402eglSwapBuffers(mDisplay, mWindowSurface);1403ASSERT_EGL_SUCCESS();14041405glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferMS.get());1406drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);14071408glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS.get());1409glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferResolved.get());1410glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1411glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferResolved.get());14121413// Check the result, especially the boundaries.1414EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Balck1415EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red1416EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green1417EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow14181419ASSERT_GL_NO_ERROR();1420}14211422// Blit color buffer to default framebuffer with linear filter.1423TEST_P(EGLPreRotationBlitFramebufferTest, BlitColorWithLinearFilter)1424{1425// http://anglebug.com/44531426ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());14271428// Flaky on Linux SwANGLE http://anglebug.com/44531429ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());14301431setWindowVisible(mOSWindow, true);14321433initializeDisplay();1434initializeSurfaceWithRGBA8888Config();14351436eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1437ASSERT_EGL_SUCCESS();14381439mOSWindow->setOrientation(300, 400);1440angle::Sleep(1000);1441eglSwapBuffers(mDisplay, mWindowSurface);1442ASSERT_EGL_SUCCESS();14431444constexpr int kSize = 128;1445glViewport(0, 0, kSize, kSize);14461447GLRenderbuffer colorbuf;1448glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1449glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, kSize, kSize);14501451GLFramebuffer framebuffer;1452glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1453glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);14541455glCheckFramebufferStatus(GL_FRAMEBUFFER);14561457glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1458glClear(GL_COLOR_BUFFER_BIT);14591460ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),1461essl31_shaders::fs::RedGreenGradient());1462drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);14631464glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1465glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);1466glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);14671468// Check the result, especially the boundaries.1469EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0); // Black1470EXPECT_PIXEL_NEAR(kSize - 1, 0, 253, 0, 0, 255, 1.0); // Red1471EXPECT_PIXEL_NEAR(0, kSize - 1, 0, 253, 0, 255, 1.0); // Green1472EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 253, 253, 0, 255, 1.0); // Yellow14731474eglSwapBuffers(mDisplay, mWindowSurface);14751476ASSERT_GL_NO_ERROR();1477}14781479// Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer1480// to blit the left and right halves of that pattern into various places within the 400x300 window1481TEST_P(EGLPreRotationBlitFramebufferTest, LeftAndRightBlitFramebuffer)1482{1483// http://anglebug.com/44531484ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());14851486// Flaky on Linux SwANGLE http://anglebug.com/44531487ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());14881489// To aid in debugging, we want this window visible1490setWindowVisible(mOSWindow, true);14911492initializeDisplay();1493initializeSurfaceWithRGBA8888Config();14941495eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1496ASSERT_EGL_SUCCESS();14971498// Init program1499GLuint program = createProgram();1500ASSERT_NE(0u, program);1501glUseProgram(program);15021503GLBuffer indexBuffer;1504GLVertexArray vertexArray;1505GLBuffer vertexBuffers[2];1506initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);1507ASSERT_GL_NO_ERROR();15081509// Create a texture-backed FBO and render the predictable pattern to it1510GLFramebuffer fbo;1511GLTexture texture;1512initializeFBO(&fbo, &texture);1513ASSERT_GL_NO_ERROR();15141515glViewport(0, 0, mSize, mSize);1516glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);1517ASSERT_GL_NO_ERROR();15181519// Ensure the predictable pattern seems correct in the FBO1520test256x256PredictablePattern(0, 0);1521ASSERT_GL_NO_ERROR();15221523// Prepare to blit to the default framebuffer and read from the FBO1524glBindFramebuffer(GL_FRAMEBUFFER, 0);1525glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1526glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1527glClearColor(0.0f, 0.0f, 0.0f, 1.0f);15281529// Blit to an offset part of the 400x300 window1530GLint xOffset = 40;1531GLint yOffset = 30;15321533//1534// Test blitting half of the FBO image to a 128x256 or 256x128 part of the default framebuffer1535// (no scaling)1536//15371538// 1st) Clear to black and blit the left and right halves of the texture to the left and right1539// halves of that different part of the window1540glClear(GL_COLOR_BUFFER_BIT);1541glViewport(xOffset, yOffset, mSize, mSize);1542glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1543glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset, yOffset, xOffset + (mSize / 2),1544yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1545glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1546yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);15471548// Swap buffers to put the image in the window (so the test can be visually checked)1549eglSwapBuffers(mDisplay, mWindowSurface);1550ASSERT_GL_NO_ERROR();15511552// Blit again to check the colors in the back buffer1553glClear(GL_COLOR_BUFFER_BIT);1554glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset, yOffset, xOffset + (mSize / 2),1555yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1556glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1557yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1558glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1559test256x256PredictablePattern(xOffset, yOffset);1560ASSERT_GL_NO_ERROR();15611562// 2nd) Clear to black and this time blit the left half of the source texture to the right half1563// of the destination window, and then blit the right half of the source texture to the left1564// half of the destination window1565glClear(GL_COLOR_BUFFER_BIT);1566glViewport(xOffset, yOffset, mSize, mSize);1567glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1568glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2),1569yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1570glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1571yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);15721573// Swap buffers to put the image in the window (so the test can be visually checked)1574eglSwapBuffers(mDisplay, mWindowSurface);1575ASSERT_GL_NO_ERROR();15761577// Blit again to check the colors in the back buffer1578glClear(GL_COLOR_BUFFER_BIT);1579glBlitFramebuffer(mSize / 2, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2),1580yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1581glBlitFramebuffer(0, 0, mSize / 2, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1582yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1583glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1584EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort + 1, yOffset + 0, GLColor::black);1585EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort + 1, yOffset + mSize - 1, GLColor::green);1586EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, GLColor::red);1587EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, GLColor::yellow);1588EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, kColorMidWayShortShort);1589EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayLong, kColorMidWayShortLong);1590EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, kColorMidWayLongShort);1591EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayLong, kColorMidWayLongLong);1592ASSERT_GL_NO_ERROR();15931594ASSERT_EGL_SUCCESS();1595}15961597// Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer1598// to blit the top and bottom halves of that pattern into various places within the 400x300 window1599TEST_P(EGLPreRotationBlitFramebufferTest, TopAndBottomBlitFramebuffer)1600{1601// http://anglebug.com/44531602ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());16031604// Flaky on Linux SwANGLE http://anglebug.com/44531605ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());16061607// To aid in debugging, we want this window visible1608setWindowVisible(mOSWindow, true);16091610initializeDisplay();1611initializeSurfaceWithRGBA8888Config();16121613eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1614ASSERT_EGL_SUCCESS();16151616// Init program1617GLuint program = createProgram();1618ASSERT_NE(0u, program);1619glUseProgram(program);16201621GLBuffer indexBuffer;1622GLVertexArray vertexArray;1623GLBuffer vertexBuffers[2];1624initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);1625ASSERT_GL_NO_ERROR();16261627// Create a texture-backed FBO and render the predictable pattern to it1628GLFramebuffer fbo;1629GLTexture texture;1630initializeFBO(&fbo, &texture);1631ASSERT_GL_NO_ERROR();16321633glViewport(0, 0, mSize, mSize);1634glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);1635ASSERT_GL_NO_ERROR();16361637// Ensure the predictable pattern seems correct in the FBO1638test256x256PredictablePattern(0, 0);1639ASSERT_GL_NO_ERROR();16401641// Prepare to blit to the default framebuffer and read from the FBO1642glBindFramebuffer(GL_FRAMEBUFFER, 0);1643glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1644glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1645glClearColor(0.0f, 0.0f, 0.0f, 1.0f);16461647// Blit to an offset part of the 400x300 window1648GLint xOffset = 40;1649GLint yOffset = 30;16501651//1652// Test blitting half of the FBO image to a 128x256 or 256x128 part of the default framebuffer1653// (no scaling)1654//16551656// 1st) Clear to black and blit the top and bottom halves of the texture to the top and bottom1657// halves of that different part of the window1658glClear(GL_COLOR_BUFFER_BIT);1659glViewport(xOffset, yOffset, mSize, mSize);1660glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1661glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset, xOffset + mSize,1662yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);1663glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,1664yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);16651666// Swap buffers to put the image in the window (so the test can be visually checked)1667eglSwapBuffers(mDisplay, mWindowSurface);1668ASSERT_GL_NO_ERROR();16691670// Blit again to check the colors in the back buffer1671glClear(GL_COLOR_BUFFER_BIT);1672glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset, xOffset + mSize,1673yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);1674glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,1675yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1676glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1677test256x256PredictablePattern(xOffset, yOffset);1678ASSERT_GL_NO_ERROR();16791680// 2nd) Clear to black and this time blit the top half of the source texture to the bottom half1681// of the destination window, and then blit the bottom half of the source texture to the top1682// half of the destination window1683glClear(GL_COLOR_BUFFER_BIT);1684glViewport(xOffset, yOffset, mSize, mSize);1685glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1686glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset + (mSize / 2), xOffset + mSize,1687yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1688glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset, xOffset + mSize,1689yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);16901691// Swap buffers to put the image in the window (so the test can be visually checked)1692eglSwapBuffers(mDisplay, mWindowSurface);1693ASSERT_GL_NO_ERROR();16941695// Blit again to check the colors in the back buffer1696glClear(GL_COLOR_BUFFER_BIT);1697glBlitFramebuffer(0, 0, mSize, mSize / 2, xOffset, yOffset + (mSize / 2), xOffset + mSize,1698yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1699glBlitFramebuffer(0, mSize / 2, mSize, mSize, xOffset, yOffset, xOffset + mSize,1700yOffset + (mSize / 2), GL_COLOR_BUFFER_BIT, GL_NEAREST);1701glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1702EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort + 1, GLColor::black);1703EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, GLColor::green);1704EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort + 1, GLColor::red);1705EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, GLColor::yellow);1706EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, kColorMidWayShortShort);1707EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, kColorMidWayShortLong);1708EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + mSize - 1, kColorMidWayLongShort);1709EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + 0, kColorMidWayLongLong);1710ASSERT_GL_NO_ERROR();17111712ASSERT_EGL_SUCCESS();1713}17141715// Draw a predictable pattern (for testing pre-rotation) into an FBO, and then use glBlitFramebuffer1716// to blit that pattern into various places within the 400x300 window, but being scaled to one-half1717// size1718TEST_P(EGLPreRotationBlitFramebufferTest, ScaledBlitFramebuffer)1719{1720// http://anglebug.com/44531721ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());17221723// Flaky on Linux SwANGLE http://anglebug.com/44531724ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());17251726// To aid in debugging, we want this window visible1727setWindowVisible(mOSWindow, true);17281729initializeDisplay();1730initializeSurfaceWithRGBA8888Config();17311732eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1733ASSERT_EGL_SUCCESS();17341735// Init program1736GLuint program = createProgram();1737ASSERT_NE(0u, program);1738glUseProgram(program);17391740GLBuffer indexBuffer;1741GLVertexArray vertexArray;1742GLBuffer vertexBuffers[2];1743initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);1744ASSERT_GL_NO_ERROR();17451746// Create a texture-backed FBO and render the predictable pattern to it1747GLFramebuffer fbo;1748GLTexture texture;1749initializeFBO(&fbo, &texture);1750ASSERT_GL_NO_ERROR();17511752glViewport(0, 0, mSize, mSize);1753glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);1754ASSERT_GL_NO_ERROR();17551756// Ensure the predictable pattern seems correct in the FBO1757test256x256PredictablePattern(0, 0);1758ASSERT_GL_NO_ERROR();17591760// Prepare to blit to the default framebuffer and read from the FBO1761glBindFramebuffer(GL_FRAMEBUFFER, 0);1762glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1763glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1764glClearColor(0.0f, 0.0f, 0.0f, 1.0f);17651766// Blit to an offset part of the 400x300 window1767GLint xOffset = 40;1768GLint yOffset = 30;17691770//1771// Test blitting the entire FBO image to a 128x256 or 256x128 part of the default framebuffer1772// (requires scaling)1773//17741775// 1st) Clear to black and blit the FBO to the left and right halves of that different part of1776// the window1777glClear(GL_COLOR_BUFFER_BIT);1778glViewport(xOffset, yOffset, mSize, mSize);1779glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1780glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2), yOffset + mSize,1781GL_COLOR_BUFFER_BIT, GL_NEAREST);1782glBlitFramebuffer(0, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1783yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);17841785// Swap buffers to put the image in the window (so the test can be visually checked)1786eglSwapBuffers(mDisplay, mWindowSurface);1787ASSERT_GL_NO_ERROR();17881789// Blit again to check the colors in the back buffer1790glClear(GL_COLOR_BUFFER_BIT);1791glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + (mSize / 2), yOffset + mSize,1792GL_COLOR_BUFFER_BIT, GL_NEAREST);1793glBlitFramebuffer(0, 0, mSize, mSize, xOffset + (mSize / 2), yOffset, xOffset + mSize,1794yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1795glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1796EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, kColorScaleHorizBlack);1797EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, kColorScaleHorizGreen);1798EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + 0, GLColor::red);1799EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayShort, yOffset + mSize - 1, GLColor::yellow);1800EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + 0, kColorScaleHorizBlack);1801EXPECT_PIXEL_COLOR_EQ(xOffset + kCoordMidWayLong, yOffset + mSize - 1, kColorScaleHorizGreen);1802EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, GLColor::red);1803EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);18041805// 2nd) Clear to black and blit the FBO to the top and bottom halves of that different part of1806// the window1807glClear(GL_COLOR_BUFFER_BIT);1808glViewport(xOffset, yOffset, mSize, mSize);1809glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1810glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + (mSize / 2),1811GL_COLOR_BUFFER_BIT, GL_NEAREST);1812glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,1813yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);18141815// Swap buffers to put the image in the window (so the test can be visually checked)1816eglSwapBuffers(mDisplay, mWindowSurface);1817ASSERT_GL_NO_ERROR();18181819// Blit again to check the colors in the back buffer1820glClear(GL_COLOR_BUFFER_BIT);1821glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + (mSize / 2),1822GL_COLOR_BUFFER_BIT, GL_NEAREST);1823glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset + (mSize / 2), xOffset + mSize,1824yOffset + mSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);1825glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1826EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + 0, kColorScaleVertBlack);1827EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + 0, kColorScaleVertRed);1828EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayShort, GLColor::green);1829EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayShort, GLColor::yellow);1830EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + kCoordMidWayLong, kColorScaleVertBlack);1831EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + kCoordMidWayLong, kColorScaleVertRed);1832EXPECT_PIXEL_COLOR_EQ(xOffset + 0, yOffset + mSize - 1, GLColor::green);1833EXPECT_PIXEL_COLOR_EQ(xOffset + mSize - 1, yOffset + mSize - 1, GLColor::yellow);1834ASSERT_GL_NO_ERROR();18351836ASSERT_EGL_SUCCESS();1837}18381839// Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x3001840// window, and then use glBlitFramebuffer to blit that pattern into an FBO1841TEST_P(EGLPreRotationBlitFramebufferTest, FboDestBlitFramebuffer)1842{1843// http://anglebug.com/44531844ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());18451846// Flaky on Linux SwANGLE http://anglebug.com/44531847ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());18481849// To aid in debugging, we want this window visible1850setWindowVisible(mOSWindow, true);18511852initializeDisplay();1853initializeSurfaceWithRGBA8888Config();18541855eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1856ASSERT_EGL_SUCCESS();18571858// Init program1859GLuint program = createProgram();1860ASSERT_NE(0u, program);1861glUseProgram(program);18621863GLBuffer indexBuffer;1864GLVertexArray vertexArray;1865GLBuffer vertexBuffers[2];1866initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);1867ASSERT_GL_NO_ERROR();18681869// Create a texture-backed FBO and render the predictable pattern to it1870GLFramebuffer fbo;1871GLTexture texture;1872initializeFBO(&fbo, &texture);1873ASSERT_GL_NO_ERROR();18741875glViewport(0, 0, mSize, mSize);1876glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);1877ASSERT_GL_NO_ERROR();18781879// Ensure the predictable pattern seems correct in the FBO1880test256x256PredictablePattern(0, 0);1881ASSERT_GL_NO_ERROR();18821883// Prepare to blit to the default framebuffer and read from the FBO1884glBindFramebuffer(GL_FRAMEBUFFER, 0);1885glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1886glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1887glClearColor(0.0f, 0.0f, 0.0f, 1.0f);18881889// Blit to an offset part of the 400x300 window1890GLint xOffset = 40;1891GLint yOffset = 30;18921893//1894// Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)1895//18961897// To get the entire predictable pattern into the default framebuffer at the desired offset,1898// blit it from the FBO1899glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1900glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1901glViewport(xOffset, yOffset, mSize, mSize);1902glClear(GL_COLOR_BUFFER_BIT);1903glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,1904GL_COLOR_BUFFER_BIT, GL_NEAREST);1905// Swap buffers to put the image in the window (so the test can be visually checked)1906eglSwapBuffers(mDisplay, mWindowSurface);1907ASSERT_GL_NO_ERROR();1908// Blit again to check the colors in the back buffer1909glClear(GL_COLOR_BUFFER_BIT);1910glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,1911GL_COLOR_BUFFER_BIT, GL_NEAREST);19121913// Clear the FBO to black and blit from the window to the FBO1914glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);1915glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);1916glViewport(0, 0, mSize, mSize);1917glClear(GL_COLOR_BUFFER_BIT);1918glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize, mSize,1919GL_COLOR_BUFFER_BIT, GL_NEAREST);19201921// Ensure the predictable pattern seems correct in the FBO1922glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1923test256x256PredictablePattern(0, 0);1924ASSERT_GL_NO_ERROR();19251926ASSERT_EGL_SUCCESS();1927}19281929// Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x3001930// window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with coordinates1931// that are partially out-of-bounds of the source1932TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceBlitFramebuffer)1933{1934// http://anglebug.com/44531935ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());19361937// Flaky on Linux SwANGLE http://anglebug.com/44531938ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());19391940// To aid in debugging, we want this window visible1941setWindowVisible(mOSWindow, true);19421943initializeDisplay();1944initializeSurfaceWithRGBA8888Config();19451946eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);1947ASSERT_EGL_SUCCESS();19481949// Init program1950GLuint program = createProgram();1951ASSERT_NE(0u, program);1952glUseProgram(program);19531954GLBuffer indexBuffer;1955GLVertexArray vertexArray;1956GLBuffer vertexBuffers[2];1957initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);1958ASSERT_GL_NO_ERROR();19591960// Create a texture-backed FBO and render the predictable pattern to it1961GLFramebuffer fbo;1962GLTexture texture;1963initializeFBO(&fbo, &texture);1964ASSERT_GL_NO_ERROR();19651966glViewport(0, 0, mSize, mSize);1967glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);1968ASSERT_GL_NO_ERROR();19691970// Ensure the predictable pattern seems correct in the FBO1971test256x256PredictablePattern(0, 0);1972ASSERT_GL_NO_ERROR();19731974// Prepare to blit to the default framebuffer and read from the FBO1975glBindFramebuffer(GL_FRAMEBUFFER, 0);1976glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1977glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1978glClearColor(0.0f, 0.0f, 0.0f, 1.0f);19791980// Blit to the origin of the 400x300 window1981GLint xOffset = 0;1982GLint yOffset = 0;19831984//1985// Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)1986//19871988// To get the entire predictable pattern into the default framebuffer at the desired offset,1989// blit it from the FBO1990glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);1991glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1992glViewport(xOffset, yOffset, mSize, mSize);1993glClear(GL_COLOR_BUFFER_BIT);1994glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,1995GL_COLOR_BUFFER_BIT, GL_NEAREST);1996// Swap buffers to put the image in the window (so the test can be visually checked)1997eglSwapBuffers(mDisplay, mWindowSurface);1998ASSERT_GL_NO_ERROR();1999// Blit again to check the colors in the back buffer2000glClear(GL_COLOR_BUFFER_BIT);2001glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,2002GL_COLOR_BUFFER_BIT, GL_NEAREST);20032004// Clear the FBO to black and blit from the window to the FBO, but give source coordinates that2005// are partially outside of the window2006xOffset = -10;2007yOffset = -15;2008glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);2009glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);2010glViewport(0, 0, mSize, mSize);2011glClear(GL_COLOR_BUFFER_BIT);2012glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize, mSize,2013GL_COLOR_BUFFER_BIT, GL_LINEAR);20142015// Ensure the predictable pattern seems correct in the FBO2016glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2017// NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to2018// the source coordinates that were outside of the source. The strip of black is xOffset2019// pixels wide on the left side, and yOffset pixels tall on the bottom side.2020EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);2021EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::black);2022EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 0, GLColor::black);2023EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 255, GLColor::black);2024EXPECT_PIXEL_COLOR_EQ(0, -yOffset - 1, GLColor::black);2025EXPECT_PIXEL_COLOR_EQ(255, -yOffset - 1, GLColor::black);2026EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 0, GLColor::black);2027EXPECT_PIXEL_COLOR_EQ(255 + xOffset, -yOffset - 1, GLColor::black);2028EXPECT_PIXEL_COLOR_EQ(0, 255 + yOffset, GLColor::black);2029EXPECT_PIXEL_COLOR_EQ(-xOffset - 1, 255 + yOffset, GLColor::black);20302031// FBO coordinate (-xOffset, -yOffset) (or (10, 15)) has the values from the bottom-left corner2032// of the source (which happens to be black). Thus, the following two tests are equivalent:2033EXPECT_PIXEL_COLOR_EQ(-xOffset, -yOffset, GLColor::black);2034EXPECT_PIXEL_COLOR_EQ(10, 15, GLColor::black);20352036// Note: the following is equivalent to (0, 0):2037EXPECT_PIXEL_COLOR_EQ(10 + xOffset, 15 + yOffset, GLColor::black);20382039EXPECT_PIXEL_COLOR_EQ(-xOffset + 1, -yOffset + 1, GLColor(1, 1, 0, 255));2040EXPECT_PIXEL_COLOR_EQ(-xOffset + 10, -yOffset + 10, GLColor(10, 10, 0, 255));2041EXPECT_PIXEL_COLOR_EQ(-xOffset + 20, -yOffset + 20, GLColor(20, 20, 0, 255));2042EXPECT_PIXEL_COLOR_EQ(-xOffset + 100, -yOffset + 100, GLColor(100, 100, 0, 255));2043EXPECT_PIXEL_COLOR_EQ(-xOffset + 200, -yOffset + 200, GLColor(200, 200, 0, 255));2044EXPECT_PIXEL_COLOR_EQ(-xOffset + 230, -yOffset + 230, GLColor(230, 230, 0, 255));2045// Note how the offset works differently when added to the same coordinate value as above. The2046// black strip causes the value to be 2X less the offset in each direction. Thus, coordinate2047// (230+xOffset, 230+yOffset) yields actual coordinate (220, 215) and red-green values2048// (230+(2*xOffset), 230+(2*yOffset)) or (210, 200). The following two tests are equivalent:2049EXPECT_PIXEL_COLOR_EQ(230 + xOffset, 230 + yOffset,2050GLColor(230 + (2 * xOffset), 230 + (2 * yOffset), 0, 255));2051EXPECT_PIXEL_COLOR_EQ(220, 215, GLColor(210, 200, 0, 255));2052// FBO coordinate (245, 240) has the highest pixel values from the source. The value of the2053// FBO pixel at (245, 240) is smaller than the same coordinate in the source because of the2054// blit's offsets. That is, the value is (245-xOffset, 240-yOffset) or (235, 225). Thus, the2055// following two tests are the same:2056EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 255 + yOffset,2057GLColor(255 + (2 * xOffset), 255 + (2 * yOffset), 0, 255));2058EXPECT_PIXEL_COLOR_EQ(245, 240, GLColor(235, 225, 0, 255));20592060// Again, the "mid-way" coordinates will get values that aren't truly mid-way:2061EXPECT_PIXEL_COLOR_EQ(2062xOffset + kCoordMidWayShort, yOffset + kCoordMidWayShort,2063GLColor(kCoordMidWayShort + (2 * xOffset), kCoordMidWayShort + (2 * yOffset), 0, 255));2064EXPECT_PIXEL_COLOR_EQ(2065xOffset + kCoordMidWayShort, yOffset + kCoordMidWayLong,2066GLColor(kCoordMidWayShort + (2 * xOffset), kCoordMidWayLong + (2 * yOffset), 0, 255));2067EXPECT_PIXEL_COLOR_EQ(2068xOffset + kCoordMidWayLong, yOffset + kCoordMidWayShort,2069GLColor(kCoordMidWayLong + (2 * xOffset), kCoordMidWayShort + (2 * yOffset), 0, 255));2070EXPECT_PIXEL_COLOR_EQ(2071xOffset + kCoordMidWayLong, yOffset + kCoordMidWayLong,2072GLColor(kCoordMidWayLong + (2 * xOffset), kCoordMidWayLong + (2 * yOffset), 0, 255));20732074// Almost Red2075EXPECT_PIXEL_COLOR_EQ(255, -yOffset, GLColor(255 + xOffset, 0, 0, 255));2076// Almost Green2077EXPECT_PIXEL_COLOR_EQ(-xOffset, 255, GLColor(0, 255 + yOffset, 0, 255));2078// Almost Yellow2079EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor(255 + xOffset, 255 + yOffset, 0, 255));20802081ASSERT_GL_NO_ERROR();20822083ASSERT_EGL_SUCCESS();2084}20852086// Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x3002087// window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with coordinates2088// that are partially out-of-bounds of the source, and cause a "stretch" to occur2089TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceWithStretchBlitFramebuffer)2090{2091// http://anglebug.com/44532092ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());20932094// Flaky on Linux SwANGLE http://anglebug.com/44532095ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());20962097// To aid in debugging, we want this window visible2098setWindowVisible(mOSWindow, true);20992100initializeDisplay();2101initializeSurfaceWithRGBA8888Config();21022103eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);2104ASSERT_EGL_SUCCESS();21052106// Init program2107GLuint program = createProgram();2108ASSERT_NE(0u, program);2109glUseProgram(program);21102111GLBuffer indexBuffer;2112GLVertexArray vertexArray;2113GLBuffer vertexBuffers[2];2114initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);2115ASSERT_GL_NO_ERROR();21162117// Create a texture-backed FBO and render the predictable pattern to it2118GLFramebuffer fbo;2119GLTexture texture;2120initializeFBO(&fbo, &texture);2121ASSERT_GL_NO_ERROR();21222123glViewport(0, 0, mSize, mSize);2124glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);2125ASSERT_GL_NO_ERROR();21262127// Ensure the predictable pattern seems correct in the FBO2128test256x256PredictablePattern(0, 0);2129ASSERT_GL_NO_ERROR();21302131// Prepare to blit to the default framebuffer and read from the FBO2132glBindFramebuffer(GL_FRAMEBUFFER, 0);2133glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);2134glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2135glClearColor(0.0f, 0.0f, 0.0f, 1.0f);21362137// Blit to the origin of the 400x300 window2138GLint xOffset = 0;2139GLint yOffset = 0;21402141//2142// Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)2143//21442145// To get the entire predictable pattern into the default framebuffer at the desired offset,2146// blit it from the FBO2147glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2148glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);2149glViewport(xOffset, yOffset, mSize, mSize);2150glClear(GL_COLOR_BUFFER_BIT);2151glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,2152GL_COLOR_BUFFER_BIT, GL_NEAREST);2153// Swap buffers to put the image in the window (so the test can be visually checked)2154eglSwapBuffers(mDisplay, mWindowSurface);2155ASSERT_GL_NO_ERROR();2156// Blit again to check the colors in the back buffer2157glClear(GL_COLOR_BUFFER_BIT);2158glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,2159GL_COLOR_BUFFER_BIT, GL_NEAREST);21602161// Clear the FBO to black and blit from the window to the FBO, but give source coordinates that2162// are partially outside of the window, but "stretch" the result by 0.5 (i.e. 2X shrink in x)2163xOffset = -10;2164yOffset = -15;2165glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);2166glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);2167glViewport(0, 0, mSize, mSize);2168glClear(GL_COLOR_BUFFER_BIT);2169glBlitFramebuffer(xOffset, yOffset, xOffset + mSize, yOffset + mSize, 0, 0, mSize / 2, mSize,2170GL_COLOR_BUFFER_BIT, GL_LINEAR);21712172// Ensure the predictable pattern seems correct in the FBO2173glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2174// NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to2175// the source coordinates that were outside of the source. The strip of black is xOffset/22176// pixels wide on the left side, and yOffset pixels tall on the bottom side.2177EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::black, 1);2178EXPECT_PIXEL_COLOR_NEAR(0, 255, GLColor::black, 1);2179EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 0, GLColor::black, 1);2180EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 255, GLColor::black, 1);2181EXPECT_PIXEL_COLOR_NEAR(0, -yOffset - 1, GLColor::black, 1);2182EXPECT_PIXEL_COLOR_NEAR(255 / 2, -yOffset - 1, GLColor::black, 1);2183EXPECT_PIXEL_COLOR_NEAR((255 + xOffset) / 2, 0, GLColor::black, 1);2184EXPECT_PIXEL_COLOR_NEAR((255 + xOffset) / 2, -yOffset - 1, GLColor::black, 1);2185EXPECT_PIXEL_COLOR_NEAR(0, 255 + yOffset, GLColor::black, 1);2186EXPECT_PIXEL_COLOR_NEAR((-xOffset / 2) - 1, 255 + yOffset, GLColor::black, 1);21872188// FBO coordinate (-xOffset, -yOffset) (or (10, 15)) has the values from the bottom-left corner2189// of the source (which happens to be black). Thus, the following two tests are equivalent:2190EXPECT_PIXEL_COLOR_NEAR(-xOffset / 2, -yOffset, GLColor::black, 1);2191EXPECT_PIXEL_COLOR_NEAR(10 + xOffset, 15 + yOffset, GLColor::black, 1);2192EXPECT_PIXEL_COLOR_NEAR(220 / 2, 215, GLColor(210, 200, 0, 255), 1);21932194EXPECT_PIXEL_COLOR_NEAR((254 + xOffset) / 2, 255 + yOffset,2195GLColor(254 + (2 * xOffset), 255 + (2 * yOffset), 0, 255), 1);2196EXPECT_PIXEL_COLOR_NEAR(254 / 2, 240, GLColor(244, 225, 0, 255), 1);21972198// Almost Red2199EXPECT_PIXEL_COLOR_NEAR(254 / 2, -yOffset, GLColor(254 + xOffset, 0, 0, 255), 1);2200// Almost Green2201EXPECT_PIXEL_COLOR_NEAR(-xOffset / 2, 255, GLColor(0, 255 + yOffset, 0, 255), 1);2202// Almost Yellow2203EXPECT_PIXEL_COLOR_NEAR(254 / 2, 255, GLColor(254 + xOffset, 255 + yOffset, 0, 255), 1);22042205ASSERT_GL_NO_ERROR();22062207ASSERT_EGL_SUCCESS();2208}22092210// Draw a predictable pattern (for testing pre-rotation) into a 256x256 portion of the 400x3002211// window, and then use glBlitFramebuffer to blit that pattern into an FBO, but with source and FBO2212// coordinates that are partially out-of-bounds of the source2213TEST_P(EGLPreRotationBlitFramebufferTest, FboDestOutOfBoundsSourceAndDestBlitFramebuffer)2214{2215// http://anglebug.com/44532216ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());22172218// Flaky on Linux SwANGLE http://anglebug.com/44532219ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());22202221// To aid in debugging, we want this window visible2222setWindowVisible(mOSWindow, true);22232224initializeDisplay();2225initializeSurfaceWithRGBA8888Config();22262227eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);2228ASSERT_EGL_SUCCESS();22292230// Init program2231GLuint program = createProgram();2232ASSERT_NE(0u, program);2233glUseProgram(program);22342235GLBuffer indexBuffer;2236GLVertexArray vertexArray;2237GLBuffer vertexBuffers[2];2238initializeGeometry(program, &indexBuffer, &vertexArray, vertexBuffers);2239ASSERT_GL_NO_ERROR();22402241// Create a texture-backed FBO and render the predictable pattern to it2242GLFramebuffer fbo;2243GLTexture texture;2244initializeFBO(&fbo, &texture);2245ASSERT_GL_NO_ERROR();22462247glViewport(0, 0, mSize, mSize);2248glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);2249ASSERT_GL_NO_ERROR();22502251// Ensure the predictable pattern seems correct in the FBO2252test256x256PredictablePattern(0, 0);2253ASSERT_GL_NO_ERROR();22542255// Prepare to blit to the default framebuffer and read from the FBO2256glBindFramebuffer(GL_FRAMEBUFFER, 0);2257glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);2258glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2259glClearColor(0.0f, 0.0f, 0.0f, 1.0f);22602261// Blit to the origin of the 400x300 window2262GLint xOffset = 0;2263GLint yOffset = 0;22642265//2266// Test blitting a 256x256 part of the default framebuffer to the entire FBO (no scaling)2267//22682269// To get the entire predictable pattern into the default framebuffer at the desired offset,2270// blit it from the FBO2271glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2272glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);2273glViewport(xOffset, yOffset, mSize, mSize);2274glClear(GL_COLOR_BUFFER_BIT);2275glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,2276GL_COLOR_BUFFER_BIT, GL_NEAREST);2277// Swap buffers to put the image in the window (so the test can be visually checked)2278eglSwapBuffers(mDisplay, mWindowSurface);2279ASSERT_GL_NO_ERROR();2280// Blit again to check the colors in the back buffer2281glClear(GL_COLOR_BUFFER_BIT);2282glBlitFramebuffer(0, 0, mSize, mSize, xOffset, yOffset, xOffset + mSize, yOffset + mSize,2283GL_COLOR_BUFFER_BIT, GL_NEAREST);22842285// Clear the FBO to black and blit from the window to the FBO, but give source coordinates that2286// are partially outside of the window, and give destination coordinates that are partially2287// outside of the FBO2288xOffset = -10;2289yOffset = -15;2290glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);2291glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);2292glViewport(0, 0, mSize, mSize);2293glClear(GL_COLOR_BUFFER_BIT);2294glBlitFramebuffer(xOffset, yOffset, (2 * xOffset) + mSize, (2 * yOffset) + mSize, -xOffset,2295-yOffset, mSize, mSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);22962297// Ensure the predictable pattern seems correct in the FBO2298glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);2299// NOTE: There is a strip of black on the left and bottom edges of the PBO, corresponding to2300// the source coordinates that were outside of the source. The strip of black is xOffset*22301// pixels wide on the left side, and yOffset*2 pixels tall on the bottom side.2302EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);2303EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::black);2304EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 0, GLColor::black);2305EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 255, GLColor::black);2306EXPECT_PIXEL_COLOR_EQ(0, (-yOffset * 2) - 1, GLColor::black);2307EXPECT_PIXEL_COLOR_EQ(255, (-yOffset * 2) - 1, GLColor::black);2308EXPECT_PIXEL_COLOR_EQ(255 + xOffset, 0, GLColor::black);2309EXPECT_PIXEL_COLOR_EQ(255 + xOffset, (-yOffset * 2) - 1, GLColor::black);2310EXPECT_PIXEL_COLOR_EQ(0, 255 + yOffset, GLColor::black);2311EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) - 1, 255 + yOffset, GLColor::black);23122313// FBO coordinate (-xOffset*2, -yOffset*2) (or (20, 30)) has the values from the bottom-left2314// corner of the source (which happens to be black). Thus, the following two tests are2315// equivalent:2316EXPECT_PIXEL_COLOR_EQ((-xOffset * 2), (-yOffset * 2), GLColor::black);2317EXPECT_PIXEL_COLOR_EQ(20, 30, GLColor::black);23182319// Note: the following is equivalent to (0, 0):2320EXPECT_PIXEL_COLOR_EQ(20 + (xOffset * 2), 30 + (yOffset * 2), GLColor::black);23212322EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 1, (-yOffset * 2) + 1, GLColor(1, 1, 0, 255));2323EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 10, (-yOffset * 2) + 10, GLColor(10, 10, 0, 255));2324EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 20, (-yOffset * 2) + 20, GLColor(20, 20, 0, 255));2325EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 100, (-yOffset * 2) + 100, GLColor(100, 100, 0, 255));2326EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 200, (-yOffset * 2) + 200, GLColor(200, 200, 0, 255));2327EXPECT_PIXEL_COLOR_EQ((-xOffset * 2) + 230, (-yOffset * 2) + 225, GLColor(230, 225, 0, 255));23282329// Almost Red2330EXPECT_PIXEL_COLOR_EQ(255, -yOffset * 2, GLColor(255 + (xOffset * 2), 0, 0, 255));2331// Almost Green2332EXPECT_PIXEL_COLOR_EQ(-xOffset * 2, 255, GLColor(0, 255 + (yOffset * 2), 0, 255));2333// Almost Yellow2334EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor(255 + (xOffset * 2), 255 + (yOffset * 2), 0, 255));23352336ASSERT_GL_NO_ERROR();23372338ASSERT_EGL_SUCCESS();2339}23402341class EGLPreRotationInterpolateAtOffsetTest : public EGLPreRotationSurfaceTest2342{2343protected:2344EGLPreRotationInterpolateAtOffsetTest() {}23452346GLuint createProgram()2347{2348// Init program2349constexpr char kVS[] =2350"#version 310 es\n"2351"#extension GL_OES_shader_multisample_interpolation : require\n"2352"in highp vec2 position;\n"2353"uniform float screen_width;\n"2354"uniform float screen_height;\n"2355"out highp vec2 v_screenPosition;\n"2356"out highp vec2 v_offset;\n"2357"void main (void)\n"2358"{\n"2359" gl_Position = vec4(position, 0, 1);\n"2360" v_screenPosition = (position.xy + vec2(1.0, 1.0)) / 2.0 * vec2(screen_width, "2361"screen_height);\n"2362" v_offset = position.xy * 0.5f;\n"2363"}";23642365constexpr char kFS[] =2366"#version 310 es\n"2367"#extension GL_OES_shader_multisample_interpolation : require\n"2368"in highp vec2 v_screenPosition;\n"2369"in highp vec2 v_offset;\n"2370"layout(location = 0) out mediump vec4 FragColor;\n"2371"void main() {\n"2372" const highp float threshold = 0.15625; // 4 subpixel bits. Assume 3 accurate bits "2373"+ 0.03125 for other errors\n"2374"\n"2375" highp vec2 pixelCenter = floor(v_screenPosition) + vec2(0.5, 0.5);\n"2376" highp vec2 offsetValue = interpolateAtOffset(v_screenPosition, v_offset);\n"2377" highp vec2 refValue = pixelCenter + v_offset;\n"2378"\n"2379" bool valuesEqual = all(lessThan(abs(offsetValue - refValue), vec2(threshold)));\n"2380" if (valuesEqual)\n"2381" FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"2382" else\n"2383" FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"2384"}";23852386return CompileProgram(kVS, kFS);2387}2388void initializeGeometry(GLuint program,2389GLBuffer *indexBuffer,2390GLVertexArray *vertexArray,2391GLBuffer *vertexBuffers)2392{2393GLint positionLocation = glGetAttribLocation(program, "position");2394ASSERT_NE(-1, positionLocation);23952396GLuint screenWidthId = glGetUniformLocation(program, "screen_width");2397GLuint screenHeightId = glGetUniformLocation(program, "screen_height");23982399glUniform1f(screenWidthId, (GLfloat)mSize);2400glUniform1f(screenHeightId, (GLfloat)mSize);24012402glBindVertexArray(*vertexArray);24032404std::vector<GLushort> indices = {0, 1, 2, 2, 3, 0};2405glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *indexBuffer);2406glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * indices.size(), &indices[0],2407GL_STATIC_DRAW);24082409std::vector<GLfloat> positionData = {// quad vertices2410-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};24112412glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);2413glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],2414GL_STATIC_DRAW);2415glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2,2416nullptr);2417glEnableVertexAttribArray(positionLocation);2418}2419};24202421// Draw with interpolateAtOffset() builtin function to pre-rotated default FBO2422TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithDefaultFBO)2423{2424// http://anglebug.com/44532425ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());24262427// Flaky on Linux SwANGLE http://anglebug.com/44532428ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());24292430// To aid in debugging, we want this window visible2431setWindowVisible(mOSWindow, true);24322433initializeDisplay();2434initializeSurfaceWithRGBA8888Config();24352436eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);2437ASSERT_EGL_SUCCESS();24382439ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation"));24402441// Init program2442GLuint program = createProgram();2443ASSERT_NE(0u, program);2444glUseProgram(program);24452446GLBuffer indexBuffer;2447GLVertexArray vertexArray;2448GLBuffer vertexBuffers;2449initializeGeometry(program, &indexBuffer, &vertexArray, &vertexBuffers);2450ASSERT_GL_NO_ERROR();24512452glViewport(0, 0, mSize, mSize);2453glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);24542455EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 255));2456EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor(0, 255, 0, 255));2457EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor(0, 255, 0, 255));2458EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor(0, 255, 0, 255));2459ASSERT_GL_NO_ERROR();24602461// Make the image visible2462eglSwapBuffers(mDisplay, mWindowSurface);2463ASSERT_EGL_SUCCESS();2464}24652466// Draw with interpolateAtOffset() builtin function to pre-rotated custom FBO2467TEST_P(EGLPreRotationInterpolateAtOffsetTest, InterpolateAtOffsetWithCustomFBO)2468{2469// http://anglebug.com/44532470ANGLE_SKIP_TEST_IF(isVulkanRenderer() && IsLinux() && IsIntel());24712472// Flaky on Linux SwANGLE http://anglebug.com/44532473ANGLE_SKIP_TEST_IF(IsLinux() && isSwiftshader());24742475// To aid in debugging, we want this window visible2476setWindowVisible(mOSWindow, true);24772478initializeDisplay();2479initializeSurfaceWithRGBA8888Config();24802481eglMakeCurrent(mDisplay, mWindowSurface, mWindowSurface, mContext);2482ASSERT_EGL_SUCCESS();24832484ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_shader_multisample_interpolation"));24852486// Init program2487GLuint program = createProgram();2488ASSERT_NE(0u, program);2489glUseProgram(program);24902491GLBuffer indexBuffer;2492GLVertexArray vertexArray;2493GLBuffer vertexBuffers;2494initializeGeometry(program, &indexBuffer, &vertexArray, &vertexBuffers);2495ASSERT_GL_NO_ERROR();24962497// Create a texture-backed FBO2498GLFramebuffer fbo;2499GLTexture texture;2500glBindTexture(GL_TEXTURE_2D, texture);2501glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2502glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2503glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2504glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2505glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mSize, mSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);2506glBindFramebuffer(GL_FRAMEBUFFER, fbo);2507glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);2508ASSERT_GL_NO_ERROR();25092510glViewport(0, 0, mSize, mSize);2511glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);25122513EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 255));2514EXPECT_PIXEL_COLOR_EQ(mSize - 1, 0, GLColor(0, 255, 0, 255));2515EXPECT_PIXEL_COLOR_EQ(0, mSize - 1, GLColor(0, 255, 0, 255));2516EXPECT_PIXEL_COLOR_EQ(mSize - 1, mSize - 1, GLColor(0, 255, 0, 255));2517ASSERT_GL_NO_ERROR();2518}25192520} // anonymous namespace25212522#ifdef Bool2523// X11 ridiculousness.2524# undef Bool2525#endif25262527GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationInterpolateAtOffsetTest);2528ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationInterpolateAtOffsetTest,2529PrintToStringParamName,2530testing::Bool(),2531WithNoFixture(ES31_VULKAN()));25322533GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationSurfaceTest);2534ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationSurfaceTest,2535PrintToStringParamName,2536testing::Bool(),2537WithNoFixture(ES2_VULKAN()),2538WithNoFixture(ES3_VULKAN()),2539WithNoFixture(ES3_VULKAN_SWIFTSHADER()));25402541GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationLargeSurfaceTest);2542ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationLargeSurfaceTest,2543PrintToStringParamName,2544testing::Bool(),2545WithNoFixture(ES2_VULKAN()),2546WithNoFixture(ES3_VULKAN()),2547WithNoFixture(ES3_VULKAN_SWIFTSHADER()));25482549GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPreRotationBlitFramebufferTest);2550ANGLE_INSTANTIATE_TEST_COMBINE_1(EGLPreRotationBlitFramebufferTest,2551PrintToStringParamName,2552testing::Bool(),2553WithNoFixture(ES2_VULKAN()),2554WithNoFixture(ES3_VULKAN()),2555WithNoFixture(ES3_VULKAN_SWIFTSHADER()));255625572558