1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program EGL Module 3e5c31af7Sopenharmony_ci * --------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2015 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Test KHR_swap_buffer_with_damage 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "teglSwapBuffersWithDamageTests.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp" 27e5c31af7Sopenharmony_ci#include "tcuSurface.hpp" 28e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include "egluNativeWindow.hpp" 31e5c31af7Sopenharmony_ci#include "egluUtil.hpp" 32e5c31af7Sopenharmony_ci#include "egluConfigFilter.hpp" 33e5c31af7Sopenharmony_ci 34e5c31af7Sopenharmony_ci#include "eglwLibrary.hpp" 35e5c31af7Sopenharmony_ci#include "eglwEnums.hpp" 36e5c31af7Sopenharmony_ci 37e5c31af7Sopenharmony_ci#include "gluDefs.hpp" 38e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp" 39e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include "glwDefs.hpp" 42e5c31af7Sopenharmony_ci#include "glwEnums.hpp" 43e5c31af7Sopenharmony_ci#include "glwFunctions.hpp" 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci#include "deRandom.hpp" 46e5c31af7Sopenharmony_ci#include "deString.h" 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ci#include <string> 49e5c31af7Sopenharmony_ci#include <vector> 50e5c31af7Sopenharmony_ci#include <sstream> 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ciusing std::string; 53e5c31af7Sopenharmony_ciusing std::vector; 54e5c31af7Sopenharmony_ciusing glw::GLubyte; 55e5c31af7Sopenharmony_ciusing tcu::IVec2; 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ciusing namespace eglw; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cinamespace deqp 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_cinamespace egl 62e5c31af7Sopenharmony_ci{ 63e5c31af7Sopenharmony_cinamespace 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci 66e5c31af7Sopenharmony_citypedef tcu::Vector<GLubyte, 3> Color; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_cienum DrawType 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_CLEAR, 71e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_RENDER 72e5c31af7Sopenharmony_ci}; 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_cienum ResizeType 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci RESIZETYPE_NONE = 0, 77e5c31af7Sopenharmony_ci RESIZETYPE_BEFORE_SWAP, 78e5c31af7Sopenharmony_ci RESIZETYPE_AFTER_SWAP, 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_ci RESIZETYPE_LAST 81e5c31af7Sopenharmony_ci}; 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_cistruct ColoredRect 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_cipublic: 86e5c31af7Sopenharmony_ci ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_); 87e5c31af7Sopenharmony_ci IVec2 bottomLeft; 88e5c31af7Sopenharmony_ci IVec2 topRight; 89e5c31af7Sopenharmony_ci Color color; 90e5c31af7Sopenharmony_ci}; 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ciColoredRect::ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_) 93e5c31af7Sopenharmony_ci : bottomLeft (bottomLeft_) 94e5c31af7Sopenharmony_ci , topRight (topRight_) 95e5c31af7Sopenharmony_ci , color (color_) 96e5c31af7Sopenharmony_ci{ 97e5c31af7Sopenharmony_ci} 98e5c31af7Sopenharmony_ci 99e5c31af7Sopenharmony_cistruct DrawCommand 100e5c31af7Sopenharmony_ci{ 101e5c31af7Sopenharmony_ci DrawCommand (DrawType drawType_, const ColoredRect& rect_); 102e5c31af7Sopenharmony_ci DrawType drawType; 103e5c31af7Sopenharmony_ci ColoredRect rect; 104e5c31af7Sopenharmony_ci}; 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_ciDrawCommand::DrawCommand (DrawType drawType_, const ColoredRect& rect_) 107e5c31af7Sopenharmony_ci : drawType (drawType_) 108e5c31af7Sopenharmony_ci , rect (rect_) 109e5c31af7Sopenharmony_ci{ 110e5c31af7Sopenharmony_ci} 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_cistruct Frame 113e5c31af7Sopenharmony_ci{ 114e5c31af7Sopenharmony_ci Frame (int width_, int height_); 115e5c31af7Sopenharmony_ci int width; 116e5c31af7Sopenharmony_ci int height; 117e5c31af7Sopenharmony_ci vector<DrawCommand> draws; 118e5c31af7Sopenharmony_ci}; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciFrame::Frame (int width_, int height_) 121e5c31af7Sopenharmony_ci : width (width_) 122e5c31af7Sopenharmony_ci , height(height_) 123e5c31af7Sopenharmony_ci{ 124e5c31af7Sopenharmony_ci} 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_citypedef vector<Frame> FrameSequence; 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci//helper function declaration 129e5c31af7Sopenharmony_ciEGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, bool preserveBuffer); 130e5c31af7Sopenharmony_civoid clearColorScreen (const glw::Functions& gl, const tcu::Vec4& clearColor); 131e5c31af7Sopenharmony_cifloat windowToDeviceCoordinates (int x, int length); 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ciclass GLES2Renderer 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_cipublic: 136e5c31af7Sopenharmony_ci GLES2Renderer (const glw::Functions& gl); 137e5c31af7Sopenharmony_ci ~GLES2Renderer (void); 138e5c31af7Sopenharmony_ci void render (int width, int height, const Frame& frame) const; 139e5c31af7Sopenharmony_ci 140e5c31af7Sopenharmony_ciprivate: 141e5c31af7Sopenharmony_ci GLES2Renderer (const GLES2Renderer&); 142e5c31af7Sopenharmony_ci GLES2Renderer& operator= (const GLES2Renderer&); 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci const glw::Functions& m_gl; 145e5c31af7Sopenharmony_ci glu::ShaderProgram m_glProgram; 146e5c31af7Sopenharmony_ci glw::GLuint m_coordLoc; 147e5c31af7Sopenharmony_ci glw::GLuint m_colorLoc; 148e5c31af7Sopenharmony_ci}; 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci// generate sources for vertex and fragment buffer 151e5c31af7Sopenharmony_ciglu::ProgramSources getSources (void) 152e5c31af7Sopenharmony_ci{ 153e5c31af7Sopenharmony_ci const char* const vertexShaderSource = 154e5c31af7Sopenharmony_ci "attribute mediump vec2 a_pos;\n" 155e5c31af7Sopenharmony_ci "attribute mediump vec4 a_color;\n" 156e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 157e5c31af7Sopenharmony_ci "void main(void)\n" 158e5c31af7Sopenharmony_ci "{\n" 159e5c31af7Sopenharmony_ci "\tv_color = a_color;\n" 160e5c31af7Sopenharmony_ci "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n" 161e5c31af7Sopenharmony_ci "}"; 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci const char* const fragmentShaderSource = 164e5c31af7Sopenharmony_ci "varying mediump vec4 v_color;\n" 165e5c31af7Sopenharmony_ci "void main(void)\n" 166e5c31af7Sopenharmony_ci "{\n" 167e5c31af7Sopenharmony_ci "\tgl_FragColor = v_color;\n" 168e5c31af7Sopenharmony_ci "}"; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci return glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource); 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ciGLES2Renderer::GLES2Renderer (const glw::Functions& gl) 174e5c31af7Sopenharmony_ci : m_gl (gl) 175e5c31af7Sopenharmony_ci , m_glProgram (gl, getSources()) 176e5c31af7Sopenharmony_ci , m_coordLoc ((glw::GLuint)-1) 177e5c31af7Sopenharmony_ci , m_colorLoc ((glw::GLuint)-1) 178e5c31af7Sopenharmony_ci{ 179e5c31af7Sopenharmony_ci m_colorLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_color"); 180e5c31af7Sopenharmony_ci m_coordLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_pos"); 181e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to get attribute locations"); 182e5c31af7Sopenharmony_ci} 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ciGLES2Renderer::~GLES2Renderer (void) 185e5c31af7Sopenharmony_ci{ 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_civoid GLES2Renderer::render (int width, int height, const Frame& frame) const 189e5c31af7Sopenharmony_ci{ 190e5c31af7Sopenharmony_ci for (size_t drawNdx = 0; drawNdx < frame.draws.size(); drawNdx++) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci const ColoredRect& coloredRect = frame.draws[drawNdx].rect; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci if (frame.draws[drawNdx].drawType == DRAWTYPE_GLES2_RENDER) 195e5c31af7Sopenharmony_ci { 196e5c31af7Sopenharmony_ci const float x1 = windowToDeviceCoordinates(coloredRect.bottomLeft.x(), width); 197e5c31af7Sopenharmony_ci const float y1 = windowToDeviceCoordinates(coloredRect.bottomLeft.y(), height); 198e5c31af7Sopenharmony_ci const float x2 = windowToDeviceCoordinates(coloredRect.topRight.x(), width); 199e5c31af7Sopenharmony_ci const float y2 = windowToDeviceCoordinates(coloredRect.topRight.y(), height); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci const glw::GLfloat coords[] = 202e5c31af7Sopenharmony_ci { 203e5c31af7Sopenharmony_ci x1, y1, 204e5c31af7Sopenharmony_ci x1, y2, 205e5c31af7Sopenharmony_ci x2, y2, 206e5c31af7Sopenharmony_ci 207e5c31af7Sopenharmony_ci x2, y2, 208e5c31af7Sopenharmony_ci x2, y1, 209e5c31af7Sopenharmony_ci x1, y1, 210e5c31af7Sopenharmony_ci }; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci const glw::GLubyte colors[] = 213e5c31af7Sopenharmony_ci { 214e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 215e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 216e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 217e5c31af7Sopenharmony_ci 218e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 219e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 220e5c31af7Sopenharmony_ci coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), 255, 221e5c31af7Sopenharmony_ci }; 222e5c31af7Sopenharmony_ci 223e5c31af7Sopenharmony_ci m_gl.useProgram(m_glProgram.getProgram()); 224e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed"); 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ci m_gl.enableVertexAttribArray(m_coordLoc); 227e5c31af7Sopenharmony_ci m_gl.enableVertexAttribArray(m_colorLoc); 228e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to enable attributes"); 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci m_gl.vertexAttribPointer(m_coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords); 231e5c31af7Sopenharmony_ci m_gl.vertexAttribPointer(m_colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors); 232e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to set attribute pointers"); 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci m_gl.drawArrays(GL_TRIANGLES, 0, DE_LENGTH_OF_ARRAY(coords)/2); 235e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays(), failed"); 236e5c31af7Sopenharmony_ci 237e5c31af7Sopenharmony_ci m_gl.disableVertexAttribArray(m_coordLoc); 238e5c31af7Sopenharmony_ci m_gl.disableVertexAttribArray(m_colorLoc); 239e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to disable attributes"); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci m_gl.useProgram(0); 242e5c31af7Sopenharmony_ci GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed"); 243e5c31af7Sopenharmony_ci } 244e5c31af7Sopenharmony_ci else if (frame.draws[drawNdx].drawType == DRAWTYPE_GLES2_CLEAR) 245e5c31af7Sopenharmony_ci { 246e5c31af7Sopenharmony_ci m_gl.enable(GL_SCISSOR_TEST); 247e5c31af7Sopenharmony_ci m_gl.scissor(coloredRect.bottomLeft.x(), coloredRect.bottomLeft.y(), 248e5c31af7Sopenharmony_ci coloredRect.topRight.x()-coloredRect.bottomLeft.x(), coloredRect.topRight.y()-coloredRect.bottomLeft.y()); 249e5c31af7Sopenharmony_ci m_gl.clearColor(coloredRect.color.x()/255.0f, coloredRect.color.y()/255.0f, coloredRect.color.z()/255.0f, 1.0f); 250e5c31af7Sopenharmony_ci m_gl.clear(GL_COLOR_BUFFER_BIT); 251e5c31af7Sopenharmony_ci m_gl.disable(GL_SCISSOR_TEST); 252e5c31af7Sopenharmony_ci } 253e5c31af7Sopenharmony_ci else 254e5c31af7Sopenharmony_ci DE_FATAL("Invalid drawtype"); 255e5c31af7Sopenharmony_ci } 256e5c31af7Sopenharmony_ci} 257e5c31af7Sopenharmony_ci 258e5c31af7Sopenharmony_ciclass SwapBuffersWithDamageTest : public TestCase 259e5c31af7Sopenharmony_ci{ 260e5c31af7Sopenharmony_cipublic: 261e5c31af7Sopenharmony_ci SwapBuffersWithDamageTest (EglTestContext& eglTestCtx, 262e5c31af7Sopenharmony_ci const vector<DrawType>& frameDrawType, 263e5c31af7Sopenharmony_ci int iterationTimes, 264e5c31af7Sopenharmony_ci ResizeType resizeType, 265e5c31af7Sopenharmony_ci const char* name, 266e5c31af7Sopenharmony_ci const char* description); 267e5c31af7Sopenharmony_ci 268e5c31af7Sopenharmony_ci ~SwapBuffersWithDamageTest (void); 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci virtual void init (void); 271e5c31af7Sopenharmony_ci void deinit (void); 272e5c31af7Sopenharmony_ci virtual IterateResult iterate (void); 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_ciprotected: 275e5c31af7Sopenharmony_ci virtual EGLConfig getConfig (const Library& egl, EGLDisplay eglDisplay); 276e5c31af7Sopenharmony_ci virtual void checkExtension (const Library& egl, EGLDisplay eglDisplay); 277e5c31af7Sopenharmony_ci void initEGLSurface (EGLConfig config); 278e5c31af7Sopenharmony_ci void initEGLContext (EGLConfig config); 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci eglu::NativeWindow* m_window; 281e5c31af7Sopenharmony_ci EGLConfig m_eglConfig; 282e5c31af7Sopenharmony_ci EGLContext m_eglContext; 283e5c31af7Sopenharmony_ci const int m_seed; 284e5c31af7Sopenharmony_ci const int m_iterationTimes; 285e5c31af7Sopenharmony_ci const vector<DrawType> m_frameDrawType; 286e5c31af7Sopenharmony_ci const ResizeType m_resizeType; 287e5c31af7Sopenharmony_ci EGLDisplay m_eglDisplay; 288e5c31af7Sopenharmony_ci EGLSurface m_eglSurface; 289e5c31af7Sopenharmony_ci glw::Functions m_gl; 290e5c31af7Sopenharmony_ci GLES2Renderer* m_gles2Renderer; 291e5c31af7Sopenharmony_ci}; 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ciSwapBuffersWithDamageTest::SwapBuffersWithDamageTest (EglTestContext& eglTestCtx, const vector<DrawType>& frameDrawType, int iterationTimes, ResizeType resizeType, const char* name, const char* description) 294e5c31af7Sopenharmony_ci : TestCase (eglTestCtx, name, description) 295e5c31af7Sopenharmony_ci , m_window (DE_NULL) 296e5c31af7Sopenharmony_ci , m_eglContext (EGL_NO_CONTEXT) 297e5c31af7Sopenharmony_ci , m_seed (deStringHash(name)) 298e5c31af7Sopenharmony_ci , m_iterationTimes (iterationTimes) 299e5c31af7Sopenharmony_ci , m_frameDrawType (frameDrawType) 300e5c31af7Sopenharmony_ci , m_resizeType (resizeType) 301e5c31af7Sopenharmony_ci , m_eglDisplay (EGL_NO_DISPLAY) 302e5c31af7Sopenharmony_ci , m_eglSurface (EGL_NO_SURFACE) 303e5c31af7Sopenharmony_ci , m_gles2Renderer (DE_NULL) 304e5c31af7Sopenharmony_ci{ 305e5c31af7Sopenharmony_ci} 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ciSwapBuffersWithDamageTest::~SwapBuffersWithDamageTest (void) 308e5c31af7Sopenharmony_ci{ 309e5c31af7Sopenharmony_ci deinit(); 310e5c31af7Sopenharmony_ci} 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ciEGLConfig SwapBuffersWithDamageTest::getConfig (const Library& egl, EGLDisplay eglDisplay) 313e5c31af7Sopenharmony_ci{ 314e5c31af7Sopenharmony_ci return getEGLConfig(egl, eglDisplay, false); 315e5c31af7Sopenharmony_ci} 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTest::checkExtension (const Library& egl, EGLDisplay eglDisplay) 318e5c31af7Sopenharmony_ci{ 319e5c31af7Sopenharmony_ci if (!eglu::hasExtension(egl, eglDisplay, "EGL_KHR_swap_buffers_with_damage")) 320e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "EGL_KHR_swap_buffers_with_damage is not supported"); 321e5c31af7Sopenharmony_ci} 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTest::init (void) 324e5c31af7Sopenharmony_ci{ 325e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_ci m_eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay()); 328e5c31af7Sopenharmony_ci m_eglConfig = getConfig(egl, m_eglDisplay); 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_ci checkExtension(egl, m_eglDisplay); 331e5c31af7Sopenharmony_ci 332e5c31af7Sopenharmony_ci initEGLSurface(m_eglConfig); 333e5c31af7Sopenharmony_ci initEGLContext(m_eglConfig); 334e5c31af7Sopenharmony_ci 335e5c31af7Sopenharmony_ci m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0)); 336e5c31af7Sopenharmony_ci m_gles2Renderer = new GLES2Renderer(m_gl); 337e5c31af7Sopenharmony_ci} 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTest::deinit (void) 340e5c31af7Sopenharmony_ci{ 341e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 342e5c31af7Sopenharmony_ci 343e5c31af7Sopenharmony_ci delete m_gles2Renderer; 344e5c31af7Sopenharmony_ci m_gles2Renderer = DE_NULL; 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci if (m_eglContext != EGL_NO_CONTEXT) 347e5c31af7Sopenharmony_ci { 348e5c31af7Sopenharmony_ci egl.makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 349e5c31af7Sopenharmony_ci egl.destroyContext(m_eglDisplay, m_eglContext); 350e5c31af7Sopenharmony_ci m_eglContext = EGL_NO_CONTEXT; 351e5c31af7Sopenharmony_ci } 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci if (m_eglSurface != EGL_NO_SURFACE) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci egl.destroySurface(m_eglDisplay, m_eglSurface); 356e5c31af7Sopenharmony_ci m_eglSurface = EGL_NO_SURFACE; 357e5c31af7Sopenharmony_ci } 358e5c31af7Sopenharmony_ci 359e5c31af7Sopenharmony_ci if (m_eglDisplay != EGL_NO_DISPLAY) 360e5c31af7Sopenharmony_ci { 361e5c31af7Sopenharmony_ci egl.terminate(m_eglDisplay); 362e5c31af7Sopenharmony_ci m_eglDisplay = EGL_NO_DISPLAY; 363e5c31af7Sopenharmony_ci } 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci delete m_window; 366e5c31af7Sopenharmony_ci m_window = DE_NULL; 367e5c31af7Sopenharmony_ci} 368e5c31af7Sopenharmony_ci 369e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTest::initEGLSurface (EGLConfig config) 370e5c31af7Sopenharmony_ci{ 371e5c31af7Sopenharmony_ci const eglu::NativeWindowFactory& factory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine()); 372e5c31af7Sopenharmony_ci m_window = factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, config, DE_NULL, 373e5c31af7Sopenharmony_ci eglu::WindowParams(480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))); 374e5c31af7Sopenharmony_ci m_eglSurface = eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, config, DE_NULL); 375e5c31af7Sopenharmony_ci} 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTest::initEGLContext (EGLConfig config) 378e5c31af7Sopenharmony_ci{ 379e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 380e5c31af7Sopenharmony_ci const EGLint attribList[] = 381e5c31af7Sopenharmony_ci { 382e5c31af7Sopenharmony_ci EGL_CONTEXT_CLIENT_VERSION, 2, 383e5c31af7Sopenharmony_ci EGL_NONE 384e5c31af7Sopenharmony_ci }; 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci egl.bindAPI(EGL_OPENGL_ES_API); 387e5c31af7Sopenharmony_ci m_eglContext = egl.createContext(m_eglDisplay, config, EGL_NO_CONTEXT, attribList); 388e5c31af7Sopenharmony_ci EGLU_CHECK_MSG(egl, "eglCreateContext"); 389e5c31af7Sopenharmony_ci TCU_CHECK(m_eglSurface != EGL_NO_SURFACE); 390e5c31af7Sopenharmony_ci egl.makeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); 391e5c31af7Sopenharmony_ci EGLU_CHECK_MSG(egl, "eglMakeCurrent"); 392e5c31af7Sopenharmony_ci} 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ciFrameSequence generateFrameSequence (const vector<DrawType>& frameDrawType, de::Random& rnd, int numFrames, int width, int height); 395e5c31af7Sopenharmony_civector<EGLint> getDamageRegion (const Frame& frame); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ciTestCase::IterateResult SwapBuffersWithDamageTest::iterate (void) 398e5c31af7Sopenharmony_ci{ 399e5c31af7Sopenharmony_ci de::Random rnd (m_seed); 400e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 401e5c31af7Sopenharmony_ci const int width = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_WIDTH); 402e5c31af7Sopenharmony_ci const int height = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_HEIGHT); 403e5c31af7Sopenharmony_ci const float clearRed = rnd.getFloat(); 404e5c31af7Sopenharmony_ci const float clearGreen = rnd.getFloat(); 405e5c31af7Sopenharmony_ci const float clearBlue = rnd.getFloat(); 406e5c31af7Sopenharmony_ci const tcu::Vec4 clearColor (clearRed, clearGreen, clearBlue, 1.0f); 407e5c31af7Sopenharmony_ci const int numFrames = 24; // (width, height) = (480, 480) --> numFrame = 24, divisible 408e5c31af7Sopenharmony_ci const FrameSequence frameSequence = generateFrameSequence(m_frameDrawType, rnd, numFrames, width, height); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 411e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci for (int iterationNdx = 0; iterationNdx < m_iterationTimes; iterationNdx++) 414e5c31af7Sopenharmony_ci { 415e5c31af7Sopenharmony_ci for (int currentFrameNdx = 0; currentFrameNdx < numFrames; currentFrameNdx++) 416e5c31af7Sopenharmony_ci { 417e5c31af7Sopenharmony_ci vector<EGLint> damageRegion = getDamageRegion(frameSequence[currentFrameNdx]); 418e5c31af7Sopenharmony_ci 419e5c31af7Sopenharmony_ci clearColorScreen(m_gl, clearColor); 420e5c31af7Sopenharmony_ci for (int ndx = 0; ndx <= currentFrameNdx; ndx++) 421e5c31af7Sopenharmony_ci m_gles2Renderer->render(width, height, frameSequence[ndx]); 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_BEFORE_SWAP) 424e5c31af7Sopenharmony_ci { 425e5c31af7Sopenharmony_ci if (currentFrameNdx % 2 == 0) 426e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 427e5c31af7Sopenharmony_ci else 428e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 429e5c31af7Sopenharmony_ci } 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, swapBuffersWithDamageKHR(m_eglDisplay, m_eglSurface, &damageRegion[0], (EGLint)damageRegion.size()/4)); 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_AFTER_SWAP) 434e5c31af7Sopenharmony_ci { 435e5c31af7Sopenharmony_ci if (currentFrameNdx % 2 == 0) 436e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 437e5c31af7Sopenharmony_ci else 438e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 439e5c31af7Sopenharmony_ci } 440e5c31af7Sopenharmony_ci } 441e5c31af7Sopenharmony_ci } 442e5c31af7Sopenharmony_ci return STOP; 443e5c31af7Sopenharmony_ci} 444e5c31af7Sopenharmony_ci 445e5c31af7Sopenharmony_ciclass SwapBuffersWithDamageAndPreserveBufferTest : public SwapBuffersWithDamageTest 446e5c31af7Sopenharmony_ci{ 447e5c31af7Sopenharmony_cipublic: 448e5c31af7Sopenharmony_ci SwapBuffersWithDamageAndPreserveBufferTest (EglTestContext& eglTestCtx, 449e5c31af7Sopenharmony_ci const vector<DrawType>& frameDrawType, 450e5c31af7Sopenharmony_ci int iterationTimes, 451e5c31af7Sopenharmony_ci ResizeType resizeType, 452e5c31af7Sopenharmony_ci const char* name, 453e5c31af7Sopenharmony_ci const char* description); 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci IterateResult iterate (void); 456e5c31af7Sopenharmony_ci 457e5c31af7Sopenharmony_ciprotected: 458e5c31af7Sopenharmony_ci EGLConfig getConfig (const Library& egl, EGLDisplay eglDisplay); 459e5c31af7Sopenharmony_ci}; 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ciSwapBuffersWithDamageAndPreserveBufferTest::SwapBuffersWithDamageAndPreserveBufferTest (EglTestContext& eglTestCtx, 462e5c31af7Sopenharmony_ci const vector<DrawType>& frameDrawType, 463e5c31af7Sopenharmony_ci int iterationTimes, 464e5c31af7Sopenharmony_ci ResizeType resizeType, 465e5c31af7Sopenharmony_ci const char* name, 466e5c31af7Sopenharmony_ci const char* description) 467e5c31af7Sopenharmony_ci : SwapBuffersWithDamageTest (eglTestCtx, frameDrawType, iterationTimes, resizeType, name, description) 468e5c31af7Sopenharmony_ci{ 469e5c31af7Sopenharmony_ci} 470e5c31af7Sopenharmony_ci 471e5c31af7Sopenharmony_ciEGLConfig SwapBuffersWithDamageAndPreserveBufferTest::getConfig (const Library& egl, EGLDisplay eglDisplay) 472e5c31af7Sopenharmony_ci{ 473e5c31af7Sopenharmony_ci return getEGLConfig(egl, eglDisplay, true); 474e5c31af7Sopenharmony_ci} 475e5c31af7Sopenharmony_ci 476e5c31af7Sopenharmony_ciTestCase::IterateResult SwapBuffersWithDamageAndPreserveBufferTest::iterate (void) 477e5c31af7Sopenharmony_ci{ 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci de::Random rnd (m_seed); 480e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 481e5c31af7Sopenharmony_ci const int width = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_WIDTH); 482e5c31af7Sopenharmony_ci const int height = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_HEIGHT); 483e5c31af7Sopenharmony_ci const float clearRed = rnd.getFloat(); 484e5c31af7Sopenharmony_ci const float clearGreen = rnd.getFloat(); 485e5c31af7Sopenharmony_ci const float clearBlue = rnd.getFloat(); 486e5c31af7Sopenharmony_ci const tcu::Vec4 clearColor (clearRed, clearGreen, clearBlue, 1.0f); 487e5c31af7Sopenharmony_ci const int numFrames = 24; // (width, height) = (480, 480) --> numFrame = 24, divisible 488e5c31af7Sopenharmony_ci const FrameSequence frameSequence = generateFrameSequence(m_frameDrawType, rnd, numFrames, width, height); 489e5c31af7Sopenharmony_ci 490e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 491e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)); 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci for (int iterationNdx = 0; iterationNdx < m_iterationTimes; iterationNdx++) 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci clearColorScreen(m_gl, clearColor); 496e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, swapBuffersWithDamageKHR(m_eglDisplay, m_eglSurface, DE_NULL, 0)); 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci for (int frameNdx = 0; frameNdx < numFrames; frameNdx++) 499e5c31af7Sopenharmony_ci { 500e5c31af7Sopenharmony_ci const Frame& currentFrame = frameSequence[frameNdx]; 501e5c31af7Sopenharmony_ci vector<EGLint> damageRegion = getDamageRegion(currentFrame); 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci m_gles2Renderer->render(width, height, currentFrame); 504e5c31af7Sopenharmony_ci 505e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_BEFORE_SWAP) 506e5c31af7Sopenharmony_ci { 507e5c31af7Sopenharmony_ci if (frameNdx % 2 == 0) 508e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 509e5c31af7Sopenharmony_ci else 510e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 511e5c31af7Sopenharmony_ci } 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, swapBuffersWithDamageKHR(m_eglDisplay, m_eglSurface, &damageRegion[0], (EGLint)damageRegion.size()/4)); 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_AFTER_SWAP) 516e5c31af7Sopenharmony_ci { 517e5c31af7Sopenharmony_ci if (frameNdx % 2 == 0) 518e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 519e5c31af7Sopenharmony_ci else 520e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 521e5c31af7Sopenharmony_ci } 522e5c31af7Sopenharmony_ci } 523e5c31af7Sopenharmony_ci } 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci return STOP; 526e5c31af7Sopenharmony_ci} 527e5c31af7Sopenharmony_ci 528e5c31af7Sopenharmony_ciclass SwapBuffersWithDamageAndBufferAgeTest : public SwapBuffersWithDamageTest 529e5c31af7Sopenharmony_ci{ 530e5c31af7Sopenharmony_cipublic: 531e5c31af7Sopenharmony_ci SwapBuffersWithDamageAndBufferAgeTest (EglTestContext& eglTestCtx, 532e5c31af7Sopenharmony_ci const vector<DrawType>& frameDrawType, 533e5c31af7Sopenharmony_ci int iterationTimes, 534e5c31af7Sopenharmony_ci ResizeType resizeType, 535e5c31af7Sopenharmony_ci const char* name, 536e5c31af7Sopenharmony_ci const char* description); 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ci IterateResult iterate (void); 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ciprotected: 541e5c31af7Sopenharmony_ci void checkExtension (const Library& egl, EGLDisplay eglDisplay); 542e5c31af7Sopenharmony_ci}; 543e5c31af7Sopenharmony_ci 544e5c31af7Sopenharmony_ciSwapBuffersWithDamageAndBufferAgeTest::SwapBuffersWithDamageAndBufferAgeTest (EglTestContext& eglTestCtx, 545e5c31af7Sopenharmony_ci const vector<DrawType>& frameDrawType, 546e5c31af7Sopenharmony_ci int iterationTimes, 547e5c31af7Sopenharmony_ci ResizeType resizeType, 548e5c31af7Sopenharmony_ci const char* name, 549e5c31af7Sopenharmony_ci const char* description) 550e5c31af7Sopenharmony_ci : SwapBuffersWithDamageTest (eglTestCtx, frameDrawType, iterationTimes, resizeType, name, description) 551e5c31af7Sopenharmony_ci{ 552e5c31af7Sopenharmony_ci} 553e5c31af7Sopenharmony_ci 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_civoid SwapBuffersWithDamageAndBufferAgeTest::checkExtension (const Library& egl, EGLDisplay eglDisplay) 556e5c31af7Sopenharmony_ci{ 557e5c31af7Sopenharmony_ci if (!eglu::hasExtension(egl, eglDisplay, "EGL_KHR_swap_buffers_with_damage")) 558e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "EGL_KHR_swap_buffers_with_damage is not supported"); 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci if (!eglu::hasExtension(egl, eglDisplay, "EGL_EXT_buffer_age")) 561e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "EGL_EXT_buffer_age not supported"); 562e5c31af7Sopenharmony_ci} 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ciTestCase::IterateResult SwapBuffersWithDamageAndBufferAgeTest::iterate (void) 565e5c31af7Sopenharmony_ci{ 566e5c31af7Sopenharmony_ci 567e5c31af7Sopenharmony_ci de::Random rnd (m_seed); 568e5c31af7Sopenharmony_ci const Library& egl = m_eglTestCtx.getLibrary(); 569e5c31af7Sopenharmony_ci const int width = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_WIDTH); 570e5c31af7Sopenharmony_ci const int height = eglu::querySurfaceInt(egl, m_eglDisplay, m_eglSurface, EGL_HEIGHT); 571e5c31af7Sopenharmony_ci const float clearRed = rnd.getFloat(); 572e5c31af7Sopenharmony_ci const float clearGreen = rnd.getFloat(); 573e5c31af7Sopenharmony_ci const float clearBlue = rnd.getFloat(); 574e5c31af7Sopenharmony_ci const tcu::Vec4 clearColor (clearRed, clearGreen, clearBlue, 1.0f); 575e5c31af7Sopenharmony_ci const int numFrames = 24; // (width, height) = (480, 480) --> numFrame = 24, divisible 576e5c31af7Sopenharmony_ci const FrameSequence frameSequence = generateFrameSequence(m_frameDrawType, rnd, numFrames, width, height); 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 579e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, surfaceAttrib(m_eglDisplay, m_eglSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED)); 580e5c31af7Sopenharmony_ci 581e5c31af7Sopenharmony_ci for (int iterationNdx = 0; iterationNdx < m_iterationTimes; iterationNdx++) 582e5c31af7Sopenharmony_ci { 583e5c31af7Sopenharmony_ci clearColorScreen(m_gl, clearColor); 584e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, swapBuffersWithDamageKHR(m_eglDisplay, m_eglSurface, DE_NULL, 0)); 585e5c31af7Sopenharmony_ci 586e5c31af7Sopenharmony_ci for (int frameNdx = 0; frameNdx < numFrames; frameNdx++) 587e5c31af7Sopenharmony_ci { 588e5c31af7Sopenharmony_ci vector<EGLint> damageRegion; 589e5c31af7Sopenharmony_ci int bufferAge = -1; 590e5c31af7Sopenharmony_ci int startFrameNdx = -1; 591e5c31af7Sopenharmony_ci int endFrameNdx = frameNdx; 592e5c31af7Sopenharmony_ci 593e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, querySurface(m_eglDisplay, m_eglSurface, EGL_BUFFER_AGE_EXT, &bufferAge)); 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci if (bufferAge < 0) // invalid buffer age 596e5c31af7Sopenharmony_ci { 597e5c31af7Sopenharmony_ci std::ostringstream stream; 598e5c31af7Sopenharmony_ci stream << "Fail, the age is invalid. Age: " << bufferAge << ", frameNdx: " << frameNdx; 599e5c31af7Sopenharmony_ci m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, stream.str().c_str()); 600e5c31af7Sopenharmony_ci return STOP; 601e5c31af7Sopenharmony_ci } 602e5c31af7Sopenharmony_ci 603e5c31af7Sopenharmony_ci if (bufferAge == 0 || bufferAge > frameNdx) 604e5c31af7Sopenharmony_ci { 605e5c31af7Sopenharmony_ci clearColorScreen(m_gl, clearColor); 606e5c31af7Sopenharmony_ci startFrameNdx = 0; 607e5c31af7Sopenharmony_ci } 608e5c31af7Sopenharmony_ci else 609e5c31af7Sopenharmony_ci startFrameNdx = frameNdx-bufferAge+1; 610e5c31af7Sopenharmony_ci 611e5c31af7Sopenharmony_ci for (int ndx = startFrameNdx; ndx <= endFrameNdx; ndx++) 612e5c31af7Sopenharmony_ci { 613e5c31af7Sopenharmony_ci const vector<EGLint> partialDamageRegion = getDamageRegion(frameSequence[ndx]); 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ci damageRegion.insert(damageRegion.end(), partialDamageRegion.begin(), partialDamageRegion.end()); 616e5c31af7Sopenharmony_ci m_gles2Renderer->render(width, height, frameSequence[ndx]); 617e5c31af7Sopenharmony_ci } 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_BEFORE_SWAP) 620e5c31af7Sopenharmony_ci { 621e5c31af7Sopenharmony_ci if (frameNdx % 2 == 0) 622e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 623e5c31af7Sopenharmony_ci else 624e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 625e5c31af7Sopenharmony_ci } 626e5c31af7Sopenharmony_ci 627e5c31af7Sopenharmony_ci EGLU_CHECK_CALL(egl, swapBuffersWithDamageKHR(m_eglDisplay, m_eglSurface, &damageRegion[0], (EGLint)damageRegion.size()/4)); 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci if (m_resizeType == RESIZETYPE_AFTER_SWAP) 630e5c31af7Sopenharmony_ci { 631e5c31af7Sopenharmony_ci if (frameNdx % 2 == 0) 632e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(width*2, height/2)); 633e5c31af7Sopenharmony_ci else 634e5c31af7Sopenharmony_ci m_window->setSurfaceSize(IVec2(height/2, width*2)); 635e5c31af7Sopenharmony_ci } 636e5c31af7Sopenharmony_ci } 637e5c31af7Sopenharmony_ci } 638e5c31af7Sopenharmony_ci return STOP; 639e5c31af7Sopenharmony_ci} 640e5c31af7Sopenharmony_ci 641e5c31af7Sopenharmony_ci// generate a frame sequence with certain frame for visual verification 642e5c31af7Sopenharmony_ciFrameSequence generateFrameSequence (const vector<DrawType>& frameDrawType, de::Random& rnd, int numFrames, int width, int height) 643e5c31af7Sopenharmony_ci{ 644e5c31af7Sopenharmony_ci const int frameDiff = height / numFrames; 645e5c31af7Sopenharmony_ci const GLubyte r = rnd.getUint8(); 646e5c31af7Sopenharmony_ci const GLubyte g = rnd.getUint8(); 647e5c31af7Sopenharmony_ci const GLubyte b = rnd.getUint8(); 648e5c31af7Sopenharmony_ci const Color color (r, g, b); 649e5c31af7Sopenharmony_ci FrameSequence frameSequence; 650e5c31af7Sopenharmony_ci 651e5c31af7Sopenharmony_ci for (int frameNdx = 0; frameNdx < numFrames; frameNdx++) 652e5c31af7Sopenharmony_ci { 653e5c31af7Sopenharmony_ci Frame frame (width, height); 654e5c31af7Sopenharmony_ci 655e5c31af7Sopenharmony_ci for (int rectNdx = 0; rectNdx < (int)frameDrawType.size(); rectNdx++) 656e5c31af7Sopenharmony_ci { 657e5c31af7Sopenharmony_ci const int rectHeight = frameDiff / (int)frameDrawType.size(); 658e5c31af7Sopenharmony_ci const ColoredRect rect (IVec2(0, frameNdx*frameDiff+rectNdx*rectHeight), IVec2(width, frameNdx*frameDiff+(rectNdx+1)*rectHeight), color); 659e5c31af7Sopenharmony_ci const DrawCommand drawCommand (frameDrawType[rectNdx], rect); 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci frame.draws.push_back(drawCommand); 662e5c31af7Sopenharmony_ci } 663e5c31af7Sopenharmony_ci frameSequence.push_back(frame); 664e5c31af7Sopenharmony_ci } 665e5c31af7Sopenharmony_ci return frameSequence; 666e5c31af7Sopenharmony_ci} 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_civector<EGLint> getDamageRegion (const Frame& frame) 669e5c31af7Sopenharmony_ci{ 670e5c31af7Sopenharmony_ci vector<EGLint> damageRegion; 671e5c31af7Sopenharmony_ci for (size_t drawNdx = 0; drawNdx < frame.draws.size(); drawNdx++) 672e5c31af7Sopenharmony_ci { 673e5c31af7Sopenharmony_ci const ColoredRect& rect = frame.draws[drawNdx].rect; 674e5c31af7Sopenharmony_ci damageRegion.push_back(rect.bottomLeft.x()); 675e5c31af7Sopenharmony_ci damageRegion.push_back(rect.bottomLeft.y()); 676e5c31af7Sopenharmony_ci damageRegion.push_back(rect.topRight.x() - rect.bottomLeft.x()); 677e5c31af7Sopenharmony_ci damageRegion.push_back(rect.topRight.y() - rect.bottomLeft.y()); 678e5c31af7Sopenharmony_ci } 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci DE_ASSERT(damageRegion.size() % 4 == 0); 681e5c31af7Sopenharmony_ci return damageRegion; 682e5c31af7Sopenharmony_ci} 683e5c31af7Sopenharmony_ci 684e5c31af7Sopenharmony_cistring generateTestName (const vector<DrawType>& frameDrawType) 685e5c31af7Sopenharmony_ci{ 686e5c31af7Sopenharmony_ci std::ostringstream stream; 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < frameDrawType.size(); ndx++) 689e5c31af7Sopenharmony_ci { 690e5c31af7Sopenharmony_ci if (frameDrawType[ndx] == DRAWTYPE_GLES2_RENDER) 691e5c31af7Sopenharmony_ci stream << "render"; 692e5c31af7Sopenharmony_ci else if (frameDrawType[ndx] == DRAWTYPE_GLES2_CLEAR) 693e5c31af7Sopenharmony_ci stream << "clear"; 694e5c31af7Sopenharmony_ci else 695e5c31af7Sopenharmony_ci DE_ASSERT(false); 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci if (ndx < frameDrawType.size()-1) 698e5c31af7Sopenharmony_ci stream << "_"; 699e5c31af7Sopenharmony_ci } 700e5c31af7Sopenharmony_ci 701e5c31af7Sopenharmony_ci return stream.str(); 702e5c31af7Sopenharmony_ci} 703e5c31af7Sopenharmony_ci 704e5c31af7Sopenharmony_cistring generateResizeGroupName (ResizeType resizeType) 705e5c31af7Sopenharmony_ci{ 706e5c31af7Sopenharmony_ci switch (resizeType) 707e5c31af7Sopenharmony_ci { 708e5c31af7Sopenharmony_ci case RESIZETYPE_NONE: 709e5c31af7Sopenharmony_ci return "no_resize"; 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci case RESIZETYPE_AFTER_SWAP: 712e5c31af7Sopenharmony_ci return "resize_after_swap"; 713e5c31af7Sopenharmony_ci 714e5c31af7Sopenharmony_ci case RESIZETYPE_BEFORE_SWAP: 715e5c31af7Sopenharmony_ci return "resize_before_swap"; 716e5c31af7Sopenharmony_ci 717e5c31af7Sopenharmony_ci default: 718e5c31af7Sopenharmony_ci DE_FATAL("Unknown resize type"); 719e5c31af7Sopenharmony_ci return ""; 720e5c31af7Sopenharmony_ci } 721e5c31af7Sopenharmony_ci} 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_cibool isWindow (const eglu::CandidateConfig& c) 724e5c31af7Sopenharmony_ci{ 725e5c31af7Sopenharmony_ci return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT; 726e5c31af7Sopenharmony_ci} 727e5c31af7Sopenharmony_ci 728e5c31af7Sopenharmony_cibool isES2Renderable (const eglu::CandidateConfig& c) 729e5c31af7Sopenharmony_ci{ 730e5c31af7Sopenharmony_ci return (c.get(EGL_RENDERABLE_TYPE) & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT; 731e5c31af7Sopenharmony_ci} 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_cibool hasPreserveSwap (const eglu::CandidateConfig& c) 734e5c31af7Sopenharmony_ci{ 735e5c31af7Sopenharmony_ci return (c.surfaceType() & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) == EGL_SWAP_BEHAVIOR_PRESERVED_BIT; 736e5c31af7Sopenharmony_ci} 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ciEGLConfig getEGLConfig (const Library& egl, EGLDisplay eglDisplay, bool preserveBuffer) 739e5c31af7Sopenharmony_ci{ 740e5c31af7Sopenharmony_ci eglu::FilterList filters; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci filters << isWindow << isES2Renderable; 743e5c31af7Sopenharmony_ci if (preserveBuffer) 744e5c31af7Sopenharmony_ci filters << hasPreserveSwap; 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci return eglu::chooseSingleConfig(egl, eglDisplay, filters); 747e5c31af7Sopenharmony_ci} 748e5c31af7Sopenharmony_ci 749e5c31af7Sopenharmony_civoid clearColorScreen (const glw::Functions& gl, const tcu::Vec4& clearColor) 750e5c31af7Sopenharmony_ci{ 751e5c31af7Sopenharmony_ci gl.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w()); 752e5c31af7Sopenharmony_ci gl.clear(GL_COLOR_BUFFER_BIT); 753e5c31af7Sopenharmony_ci} 754e5c31af7Sopenharmony_ci 755e5c31af7Sopenharmony_cifloat windowToDeviceCoordinates (int x, int length) 756e5c31af7Sopenharmony_ci{ 757e5c31af7Sopenharmony_ci return (2.0f * float(x) / float(length)) - 1.0f; 758e5c31af7Sopenharmony_ci} 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_ci} // anonymous 761e5c31af7Sopenharmony_ci 762e5c31af7Sopenharmony_ciSwapBuffersWithDamageTests::SwapBuffersWithDamageTests (EglTestContext& eglTestCtx) 763e5c31af7Sopenharmony_ci : TestCaseGroup(eglTestCtx, "swap_buffers_with_damage", "Swap buffers with damages tests") 764e5c31af7Sopenharmony_ci{ 765e5c31af7Sopenharmony_ci} 766e5c31af7Sopenharmony_ci 767e5c31af7Sopenharmony_civoid SwapBuffersWithDamageTests::init (void) 768e5c31af7Sopenharmony_ci{ 769e5c31af7Sopenharmony_ci const DrawType clearRender[2] = 770e5c31af7Sopenharmony_ci { 771e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_CLEAR, 772e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_RENDER 773e5c31af7Sopenharmony_ci }; 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci const DrawType renderClear[2] = 776e5c31af7Sopenharmony_ci { 777e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_RENDER, 778e5c31af7Sopenharmony_ci DRAWTYPE_GLES2_CLEAR 779e5c31af7Sopenharmony_ci }; 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci const ResizeType resizeTypes[] = 782e5c31af7Sopenharmony_ci { 783e5c31af7Sopenharmony_ci RESIZETYPE_NONE, 784e5c31af7Sopenharmony_ci RESIZETYPE_BEFORE_SWAP, 785e5c31af7Sopenharmony_ci RESIZETYPE_AFTER_SWAP 786e5c31af7Sopenharmony_ci }; 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ci vector< vector<DrawType> > frameDrawTypes; 789e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (1, DRAWTYPE_GLES2_CLEAR)); 790e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (1, DRAWTYPE_GLES2_RENDER)); 791e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (2, DRAWTYPE_GLES2_CLEAR)); 792e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (2, DRAWTYPE_GLES2_RENDER)); 793e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (DE_ARRAY_BEGIN(clearRender), DE_ARRAY_END(clearRender))); 794e5c31af7Sopenharmony_ci frameDrawTypes.push_back(vector<DrawType> (DE_ARRAY_BEGIN(renderClear), DE_ARRAY_END(renderClear))); 795e5c31af7Sopenharmony_ci 796e5c31af7Sopenharmony_ci for (size_t resizeTypeNdx = 0; resizeTypeNdx < DE_LENGTH_OF_ARRAY(resizeTypes); resizeTypeNdx++) 797e5c31af7Sopenharmony_ci { 798e5c31af7Sopenharmony_ci const ResizeType resizeType = resizeTypes[resizeTypeNdx]; 799e5c31af7Sopenharmony_ci TestCaseGroup* const resizeGroup = new TestCaseGroup(m_eglTestCtx, generateResizeGroupName(resizeType).c_str(), ""); 800e5c31af7Sopenharmony_ci 801e5c31af7Sopenharmony_ci for (size_t drawTypeNdx = 0; drawTypeNdx < frameDrawTypes.size(); drawTypeNdx++) 802e5c31af7Sopenharmony_ci { 803e5c31af7Sopenharmony_ci string name = generateTestName(frameDrawTypes[drawTypeNdx]); 804e5c31af7Sopenharmony_ci resizeGroup->addChild(new SwapBuffersWithDamageTest(m_eglTestCtx, frameDrawTypes[drawTypeNdx], 4, resizeType, name.c_str(), "")); 805e5c31af7Sopenharmony_ci } 806e5c31af7Sopenharmony_ci 807e5c31af7Sopenharmony_ci for (size_t drawTypeNdx = 0; drawTypeNdx < frameDrawTypes.size(); drawTypeNdx++) 808e5c31af7Sopenharmony_ci { 809e5c31af7Sopenharmony_ci string name = "preserve_buffer_" + generateTestName(frameDrawTypes[drawTypeNdx]); 810e5c31af7Sopenharmony_ci resizeGroup->addChild(new SwapBuffersWithDamageAndPreserveBufferTest(m_eglTestCtx, frameDrawTypes[drawTypeNdx], 4, resizeType, name.c_str(), "")); 811e5c31af7Sopenharmony_ci } 812e5c31af7Sopenharmony_ci 813e5c31af7Sopenharmony_ci for (size_t drawTypeNdx = 0; drawTypeNdx < frameDrawTypes.size(); drawTypeNdx++) 814e5c31af7Sopenharmony_ci { 815e5c31af7Sopenharmony_ci string name = "buffer_age_" + generateTestName(frameDrawTypes[drawTypeNdx]); 816e5c31af7Sopenharmony_ci resizeGroup->addChild(new SwapBuffersWithDamageAndBufferAgeTest(m_eglTestCtx, frameDrawTypes[drawTypeNdx], 4, resizeType, name.c_str(), "")); 817e5c31af7Sopenharmony_ci } 818e5c31af7Sopenharmony_ci 819e5c31af7Sopenharmony_ci addChild(resizeGroup); 820e5c31af7Sopenharmony_ci } 821e5c31af7Sopenharmony_ci} 822e5c31af7Sopenharmony_ci 823e5c31af7Sopenharmony_ci} // egl 824e5c31af7Sopenharmony_ci} // deqp 825