xref: /aosp_15_r20/external/deqp/modules/egl/teglResizeTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program EGL Module
3*35238bceSAndroid Build Coastguard Worker  * ---------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Tests for resizing the native window of a surface.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "teglResizeTests.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "teglSimpleConfigCase.hpp"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuPlatform.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuInterval.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuResultCollector.hpp"
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker #include "egluNativeDisplay.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "egluNativeWindow.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "egluNativePixmap.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "egluUnique.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "egluUtil.hpp"
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker #include "eglwLibrary.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "eglwEnums.hpp"
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker #include "gluDefs.hpp"
46*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
50*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker #include "deThread.h"
53*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker #include <sstream>
56*35238bceSAndroid Build Coastguard Worker 
57*35238bceSAndroid Build Coastguard Worker namespace deqp
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker namespace egl
60*35238bceSAndroid Build Coastguard Worker {
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker using de::MovePtr;
63*35238bceSAndroid Build Coastguard Worker using eglu::AttribMap;
64*35238bceSAndroid Build Coastguard Worker using eglu::NativeDisplay;
65*35238bceSAndroid Build Coastguard Worker using eglu::NativeWindow;
66*35238bceSAndroid Build Coastguard Worker using eglu::NativeWindowFactory;
67*35238bceSAndroid Build Coastguard Worker using eglu::ScopedCurrentContext;
68*35238bceSAndroid Build Coastguard Worker using eglu::UniqueContext;
69*35238bceSAndroid Build Coastguard Worker using eglu::UniqueSurface;
70*35238bceSAndroid Build Coastguard Worker using eglu::WindowParams;
71*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
72*35238bceSAndroid Build Coastguard Worker using std::string;
73*35238bceSAndroid Build Coastguard Worker using std::vector;
74*35238bceSAndroid Build Coastguard Worker using tcu::CommandLine;
75*35238bceSAndroid Build Coastguard Worker using tcu::ConstPixelBufferAccess;
76*35238bceSAndroid Build Coastguard Worker using tcu::Interval;
77*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
78*35238bceSAndroid Build Coastguard Worker using tcu::ResultCollector;
79*35238bceSAndroid Build Coastguard Worker using tcu::Surface;
80*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
81*35238bceSAndroid Build Coastguard Worker using tcu::UVec4;
82*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
83*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
84*35238bceSAndroid Build Coastguard Worker using namespace eglw;
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker typedef eglu::WindowParams::Visibility Visibility;
87*35238bceSAndroid Build Coastguard Worker typedef TestCase::IterateResult IterateResult;
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker struct ResizeParams
90*35238bceSAndroid Build Coastguard Worker {
91*35238bceSAndroid Build Coastguard Worker     string name;
92*35238bceSAndroid Build Coastguard Worker     string description;
93*35238bceSAndroid Build Coastguard Worker     IVec2 oldSize;
94*35238bceSAndroid Build Coastguard Worker     IVec2 newSize;
95*35238bceSAndroid Build Coastguard Worker };
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker class ResizeTest : public TestCase
98*35238bceSAndroid Build Coastguard Worker {
99*35238bceSAndroid Build Coastguard Worker public:
ResizeTest(EglTestContext & eglTestCtx,const ResizeParams & params)100*35238bceSAndroid Build Coastguard Worker     ResizeTest(EglTestContext &eglTestCtx, const ResizeParams &params)
101*35238bceSAndroid Build Coastguard Worker         : TestCase(eglTestCtx, params.name.c_str(), params.description.c_str())
102*35238bceSAndroid Build Coastguard Worker         , m_oldSize(params.oldSize)
103*35238bceSAndroid Build Coastguard Worker         , m_newSize(params.newSize)
104*35238bceSAndroid Build Coastguard Worker         , m_display(EGL_NO_DISPLAY)
105*35238bceSAndroid Build Coastguard Worker         , m_config(DE_NULL)
106*35238bceSAndroid Build Coastguard Worker         , m_log(m_testCtx.getLog())
107*35238bceSAndroid Build Coastguard Worker         , m_status(m_log)
108*35238bceSAndroid Build Coastguard Worker     {
109*35238bceSAndroid Build Coastguard Worker     }
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker     void init(void);
112*35238bceSAndroid Build Coastguard Worker     void deinit(void);
113*35238bceSAndroid Build Coastguard Worker 
114*35238bceSAndroid Build Coastguard Worker protected:
surfaceType(void) const115*35238bceSAndroid Build Coastguard Worker     virtual EGLenum surfaceType(void) const
116*35238bceSAndroid Build Coastguard Worker     {
117*35238bceSAndroid Build Coastguard Worker         return EGL_WINDOW_BIT;
118*35238bceSAndroid Build Coastguard Worker     }
119*35238bceSAndroid Build Coastguard Worker     void resize(IVec2 size);
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker     const IVec2 m_oldSize;
122*35238bceSAndroid Build Coastguard Worker     const IVec2 m_newSize;
123*35238bceSAndroid Build Coastguard Worker     EGLDisplay m_display;
124*35238bceSAndroid Build Coastguard Worker     EGLConfig m_config;
125*35238bceSAndroid Build Coastguard Worker     MovePtr<NativeWindow> m_nativeWindow;
126*35238bceSAndroid Build Coastguard Worker     MovePtr<UniqueSurface> m_surface;
127*35238bceSAndroid Build Coastguard Worker     MovePtr<UniqueContext> m_context;
128*35238bceSAndroid Build Coastguard Worker     TestLog &m_log;
129*35238bceSAndroid Build Coastguard Worker     ResultCollector m_status;
130*35238bceSAndroid Build Coastguard Worker     glw::Functions m_gl;
131*35238bceSAndroid Build Coastguard Worker };
132*35238bceSAndroid Build Coastguard Worker 
getEGLConfig(const Library & egl,const EGLDisplay eglDisplay,EGLenum surfaceType)133*35238bceSAndroid Build Coastguard Worker EGLConfig getEGLConfig(const Library &egl, const EGLDisplay eglDisplay, EGLenum surfaceType)
134*35238bceSAndroid Build Coastguard Worker {
135*35238bceSAndroid Build Coastguard Worker     AttribMap attribMap;
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker     attribMap[EGL_SURFACE_TYPE]    = surfaceType;
138*35238bceSAndroid Build Coastguard Worker     attribMap[EGL_RENDERABLE_TYPE] = EGL_OPENGL_ES2_BIT;
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker     return eglu::chooseSingleConfig(egl, eglDisplay, attribMap);
141*35238bceSAndroid Build Coastguard Worker }
142*35238bceSAndroid Build Coastguard Worker 
init(void)143*35238bceSAndroid Build Coastguard Worker void ResizeTest::init(void)
144*35238bceSAndroid Build Coastguard Worker {
145*35238bceSAndroid Build Coastguard Worker     TestCase::init();
146*35238bceSAndroid Build Coastguard Worker 
147*35238bceSAndroid Build Coastguard Worker     const Library &egl          = m_eglTestCtx.getLibrary();
148*35238bceSAndroid Build Coastguard Worker     const CommandLine &cmdLine  = m_testCtx.getCommandLine();
149*35238bceSAndroid Build Coastguard Worker     const EGLDisplay eglDisplay = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
150*35238bceSAndroid Build Coastguard Worker     const EGLConfig eglConfig   = getEGLConfig(egl, eglDisplay, surfaceType());
151*35238bceSAndroid Build Coastguard Worker     const EGLint ctxAttribs[]   = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
152*35238bceSAndroid Build Coastguard Worker     EGLContext eglContext       = egl.createContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, ctxAttribs);
153*35238bceSAndroid Build Coastguard Worker     EGLU_CHECK_MSG(egl, "eglCreateContext()");
154*35238bceSAndroid Build Coastguard Worker     MovePtr<UniqueContext> context(new UniqueContext(egl, eglDisplay, eglContext));
155*35238bceSAndroid Build Coastguard Worker     const EGLint configId        = eglu::getConfigAttribInt(egl, eglDisplay, eglConfig, EGL_CONFIG_ID);
156*35238bceSAndroid Build Coastguard Worker     const Visibility visibility  = eglu::parseWindowVisibility(cmdLine);
157*35238bceSAndroid Build Coastguard Worker     NativeDisplay &nativeDisplay = m_eglTestCtx.getNativeDisplay();
158*35238bceSAndroid Build Coastguard Worker     const NativeWindowFactory &windowFactory =
159*35238bceSAndroid Build Coastguard Worker         eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), cmdLine);
160*35238bceSAndroid Build Coastguard Worker 
161*35238bceSAndroid Build Coastguard Worker     const WindowParams windowParams(m_oldSize.x(), m_oldSize.y(), visibility);
162*35238bceSAndroid Build Coastguard Worker     MovePtr<NativeWindow> nativeWindow(
163*35238bceSAndroid Build Coastguard Worker         windowFactory.createWindow(&nativeDisplay, eglDisplay, eglConfig, DE_NULL, windowParams));
164*35238bceSAndroid Build Coastguard Worker     const EGLSurface eglSurface =
165*35238bceSAndroid Build Coastguard Worker         eglu::createWindowSurface(nativeDisplay, *nativeWindow, eglDisplay, eglConfig, DE_NULL);
166*35238bceSAndroid Build Coastguard Worker     MovePtr<UniqueSurface> surface(new UniqueSurface(egl, eglDisplay, eglSurface));
167*35238bceSAndroid Build Coastguard Worker 
168*35238bceSAndroid Build Coastguard Worker     m_log << TestLog::Message << "Chose EGLConfig with id " << configId << ".\n"
169*35238bceSAndroid Build Coastguard Worker           << "Created initial surface with size " << m_oldSize << TestLog::EndMessage;
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker     m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2, 0));
172*35238bceSAndroid Build Coastguard Worker     m_config       = eglConfig;
173*35238bceSAndroid Build Coastguard Worker     m_surface      = surface;
174*35238bceSAndroid Build Coastguard Worker     m_context      = context;
175*35238bceSAndroid Build Coastguard Worker     m_display      = eglDisplay;
176*35238bceSAndroid Build Coastguard Worker     m_nativeWindow = nativeWindow;
177*35238bceSAndroid Build Coastguard Worker     EGLU_CHECK_MSG(egl, "init");
178*35238bceSAndroid Build Coastguard Worker }
179*35238bceSAndroid Build Coastguard Worker 
deinit(void)180*35238bceSAndroid Build Coastguard Worker void ResizeTest::deinit(void)
181*35238bceSAndroid Build Coastguard Worker {
182*35238bceSAndroid Build Coastguard Worker     m_config = DE_NULL;
183*35238bceSAndroid Build Coastguard Worker     m_context.clear();
184*35238bceSAndroid Build Coastguard Worker     m_surface.clear();
185*35238bceSAndroid Build Coastguard Worker     m_nativeWindow.clear();
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker     if (m_display != EGL_NO_DISPLAY)
188*35238bceSAndroid Build Coastguard Worker     {
189*35238bceSAndroid Build Coastguard Worker         m_eglTestCtx.getLibrary().terminate(m_display);
190*35238bceSAndroid Build Coastguard Worker         m_display = EGL_NO_DISPLAY;
191*35238bceSAndroid Build Coastguard Worker     }
192*35238bceSAndroid Build Coastguard Worker }
193*35238bceSAndroid Build Coastguard Worker 
resize(IVec2 size)194*35238bceSAndroid Build Coastguard Worker void ResizeTest::resize(IVec2 size)
195*35238bceSAndroid Build Coastguard Worker {
196*35238bceSAndroid Build Coastguard Worker     m_nativeWindow->setSurfaceSize(size);
197*35238bceSAndroid Build Coastguard Worker     m_testCtx.getPlatform().processEvents();
198*35238bceSAndroid Build Coastguard Worker     m_log << TestLog::Message << "Resized surface to size " << size << TestLog::EndMessage;
199*35238bceSAndroid Build Coastguard Worker }
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker class ChangeSurfaceSizeCase : public ResizeTest
202*35238bceSAndroid Build Coastguard Worker {
203*35238bceSAndroid Build Coastguard Worker public:
ChangeSurfaceSizeCase(EglTestContext & eglTestCtx,const ResizeParams & params)204*35238bceSAndroid Build Coastguard Worker     ChangeSurfaceSizeCase(EglTestContext &eglTestCtx, const ResizeParams &params) : ResizeTest(eglTestCtx, params)
205*35238bceSAndroid Build Coastguard Worker     {
206*35238bceSAndroid Build Coastguard Worker     }
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
209*35238bceSAndroid Build Coastguard Worker };
210*35238bceSAndroid Build Coastguard Worker 
drawRectangle(const glw::Functions & gl,IVec2 pos,IVec2 size,Vec3 color)211*35238bceSAndroid Build Coastguard Worker void drawRectangle(const glw::Functions &gl, IVec2 pos, IVec2 size, Vec3 color)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker     gl.clearColor(color.x(), color.y(), color.z(), 1.0);
214*35238bceSAndroid Build Coastguard Worker     gl.scissor(pos.x(), pos.y(), size.x(), size.y());
215*35238bceSAndroid Build Coastguard Worker     gl.enable(GL_SCISSOR_TEST);
216*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
217*35238bceSAndroid Build Coastguard Worker     gl.disable(GL_SCISSOR_TEST);
218*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Rectangle drawing with glScissor and glClear failed.");
219*35238bceSAndroid Build Coastguard Worker }
220*35238bceSAndroid Build Coastguard Worker 
initSurface(const glw::Functions & gl,IVec2 oldSize)221*35238bceSAndroid Build Coastguard Worker void initSurface(const glw::Functions &gl, IVec2 oldSize)
222*35238bceSAndroid Build Coastguard Worker {
223*35238bceSAndroid Build Coastguard Worker     const Vec3 frameColor(0.0f, 0.0f, 1.0f);
224*35238bceSAndroid Build Coastguard Worker     const Vec3 fillColor(1.0f, 0.0f, 0.0f);
225*35238bceSAndroid Build Coastguard Worker     const Vec3 markColor(0.0f, 1.0f, 0.0f);
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, IVec2(0, 0), oldSize, frameColor);
228*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, IVec2(2, 2), oldSize - IVec2(4, 4), fillColor);
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, IVec2(0, 0), IVec2(8, 4), markColor);
231*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, oldSize - IVec2(16, 16), IVec2(8, 4), markColor);
232*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, IVec2(0, oldSize.y() - 16), IVec2(8, 4), markColor);
233*35238bceSAndroid Build Coastguard Worker     drawRectangle(gl, IVec2(oldSize.x() - 16, 0), IVec2(8, 4), markColor);
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker 
compareRectangles(const ConstPixelBufferAccess & rectA,const ConstPixelBufferAccess & rectB)236*35238bceSAndroid Build Coastguard Worker bool compareRectangles(const ConstPixelBufferAccess &rectA, const ConstPixelBufferAccess &rectB)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker     const int width  = rectA.getWidth();
239*35238bceSAndroid Build Coastguard Worker     const int height = rectA.getHeight();
240*35238bceSAndroid Build Coastguard Worker     const int depth  = rectA.getDepth();
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker     if (rectB.getWidth() != width || rectB.getHeight() != height || rectB.getDepth() != depth)
243*35238bceSAndroid Build Coastguard Worker         return false;
244*35238bceSAndroid Build Coastguard Worker 
245*35238bceSAndroid Build Coastguard Worker     for (int z = 0; z < depth; ++z)
246*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < height; ++y)
247*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < width; ++x)
248*35238bceSAndroid Build Coastguard Worker                 if (rectA.getPixel(x, y, z) != rectB.getPixel(x, y, z))
249*35238bceSAndroid Build Coastguard Worker                     return false;
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker     return true;
252*35238bceSAndroid Build Coastguard Worker }
253*35238bceSAndroid Build Coastguard Worker 
254*35238bceSAndroid Build Coastguard Worker // Check whether `oldSurface` and `newSurface` share a common corner.
compareCorners(const Surface & oldSurface,const Surface & newSurface)255*35238bceSAndroid Build Coastguard Worker bool compareCorners(const Surface &oldSurface, const Surface &newSurface)
256*35238bceSAndroid Build Coastguard Worker {
257*35238bceSAndroid Build Coastguard Worker     const int oldWidth  = oldSurface.getWidth();
258*35238bceSAndroid Build Coastguard Worker     const int oldHeight = oldSurface.getHeight();
259*35238bceSAndroid Build Coastguard Worker     const int newWidth  = newSurface.getWidth();
260*35238bceSAndroid Build Coastguard Worker     const int newHeight = newSurface.getHeight();
261*35238bceSAndroid Build Coastguard Worker     const int minWidth  = de::min(oldWidth, newWidth);
262*35238bceSAndroid Build Coastguard Worker     const int minHeight = de::min(oldHeight, newHeight);
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker     for (int xCorner = 0; xCorner < 2; ++xCorner)
265*35238bceSAndroid Build Coastguard Worker     {
266*35238bceSAndroid Build Coastguard Worker         const int oldX = xCorner == 0 ? 0 : oldWidth - minWidth;
267*35238bceSAndroid Build Coastguard Worker         const int newX = xCorner == 0 ? 0 : newWidth - minWidth;
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker         for (int yCorner = 0; yCorner < 2; ++yCorner)
270*35238bceSAndroid Build Coastguard Worker         {
271*35238bceSAndroid Build Coastguard Worker             const int oldY                   = yCorner == 0 ? 0 : oldHeight - minHeight;
272*35238bceSAndroid Build Coastguard Worker             const int newY                   = yCorner == 0 ? 0 : newHeight - minHeight;
273*35238bceSAndroid Build Coastguard Worker             ConstPixelBufferAccess oldAccess = getSubregion(oldSurface.getAccess(), oldX, oldY, minWidth, minHeight);
274*35238bceSAndroid Build Coastguard Worker             ConstPixelBufferAccess newAccess = getSubregion(newSurface.getAccess(), newX, newY, minWidth, minHeight);
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker             if (compareRectangles(oldAccess, newAccess))
277*35238bceSAndroid Build Coastguard Worker                 return true;
278*35238bceSAndroid Build Coastguard Worker         }
279*35238bceSAndroid Build Coastguard Worker     }
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker     return false;
282*35238bceSAndroid Build Coastguard Worker }
283*35238bceSAndroid Build Coastguard Worker 
readSurface(const glw::Functions & gl,IVec2 size)284*35238bceSAndroid Build Coastguard Worker Surface readSurface(const glw::Functions &gl, IVec2 size)
285*35238bceSAndroid Build Coastguard Worker {
286*35238bceSAndroid Build Coastguard Worker     Surface ret(size.x(), size.y());
287*35238bceSAndroid Build Coastguard Worker     gl.readPixels(0, 0, size.x(), size.y(), GL_RGBA, GL_UNSIGNED_BYTE, ret.getAccess().getDataPtr());
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() failed");
290*35238bceSAndroid Build Coastguard Worker     return ret;
291*35238bceSAndroid Build Coastguard Worker }
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker template <typename T>
hasBits(T bitSet,T requiredBits)294*35238bceSAndroid Build Coastguard Worker inline bool hasBits(T bitSet, T requiredBits)
295*35238bceSAndroid Build Coastguard Worker {
296*35238bceSAndroid Build Coastguard Worker     return (bitSet & requiredBits) == requiredBits;
297*35238bceSAndroid Build Coastguard Worker }
298*35238bceSAndroid Build Coastguard Worker 
getNativeSurfaceSize(const NativeWindow & nativeWindow,IVec2 reqSize)299*35238bceSAndroid Build Coastguard Worker IVec2 getNativeSurfaceSize(const NativeWindow &nativeWindow, IVec2 reqSize)
300*35238bceSAndroid Build Coastguard Worker {
301*35238bceSAndroid Build Coastguard Worker     if (hasBits(nativeWindow.getCapabilities(), NativeWindow::CAPABILITY_GET_SURFACE_SIZE))
302*35238bceSAndroid Build Coastguard Worker         return nativeWindow.getSurfaceSize();
303*35238bceSAndroid Build Coastguard Worker     return reqSize; // assume we got the requested size
304*35238bceSAndroid Build Coastguard Worker }
305*35238bceSAndroid Build Coastguard Worker 
checkSurfaceSize(const Library & egl,EGLDisplay eglDisplay,EGLSurface eglSurface,const NativeWindow & nativeWindow,IVec2 reqSize,ResultCollector & status)306*35238bceSAndroid Build Coastguard Worker IVec2 checkSurfaceSize(const Library &egl, EGLDisplay eglDisplay, EGLSurface eglSurface,
307*35238bceSAndroid Build Coastguard Worker                        const NativeWindow &nativeWindow, IVec2 reqSize, ResultCollector &status)
308*35238bceSAndroid Build Coastguard Worker {
309*35238bceSAndroid Build Coastguard Worker     const IVec2 nativeSize = getNativeSurfaceSize(nativeWindow, reqSize);
310*35238bceSAndroid Build Coastguard Worker     IVec2 eglSize          = eglu::getSurfaceSize(egl, eglDisplay, eglSurface);
311*35238bceSAndroid Build Coastguard Worker     ostringstream oss;
312*35238bceSAndroid Build Coastguard Worker 
313*35238bceSAndroid Build Coastguard Worker     oss << "Size of EGL surface " << eglSize << " differs from size of native window " << nativeSize;
314*35238bceSAndroid Build Coastguard Worker     status.check(eglSize == nativeSize, oss.str());
315*35238bceSAndroid Build Coastguard Worker 
316*35238bceSAndroid Build Coastguard Worker     return eglSize;
317*35238bceSAndroid Build Coastguard Worker }
318*35238bceSAndroid Build Coastguard Worker 
iterate(void)319*35238bceSAndroid Build Coastguard Worker IterateResult ChangeSurfaceSizeCase::iterate(void)
320*35238bceSAndroid Build Coastguard Worker {
321*35238bceSAndroid Build Coastguard Worker     const Library &egl = m_eglTestCtx.getLibrary();
322*35238bceSAndroid Build Coastguard Worker     ScopedCurrentContext currentCtx(egl, m_display, **m_surface, **m_surface, **m_context);
323*35238bceSAndroid Build Coastguard Worker     egl.swapBuffers(m_display, **m_surface);
324*35238bceSAndroid Build Coastguard Worker     IVec2 oldEglSize = checkSurfaceSize(egl, m_display, **m_surface, *m_nativeWindow, m_oldSize, m_status);
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker     initSurface(m_gl, oldEglSize);
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker     this->resize(m_newSize);
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker     egl.swapBuffers(m_display, **m_surface);
331*35238bceSAndroid Build Coastguard Worker     EGLU_CHECK_MSG(egl, "eglSwapBuffers()");
332*35238bceSAndroid Build Coastguard Worker     checkSurfaceSize(egl, m_display, **m_surface, *m_nativeWindow, m_newSize, m_status);
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker     m_status.setTestContextResult(m_testCtx);
335*35238bceSAndroid Build Coastguard Worker     return STOP;
336*35238bceSAndroid Build Coastguard Worker }
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker class PreserveBackBufferCase : public ResizeTest
339*35238bceSAndroid Build Coastguard Worker {
340*35238bceSAndroid Build Coastguard Worker public:
PreserveBackBufferCase(EglTestContext & eglTestCtx,const ResizeParams & params)341*35238bceSAndroid Build Coastguard Worker     PreserveBackBufferCase(EglTestContext &eglTestCtx, const ResizeParams &params) : ResizeTest(eglTestCtx, params)
342*35238bceSAndroid Build Coastguard Worker     {
343*35238bceSAndroid Build Coastguard Worker     }
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
346*35238bceSAndroid Build Coastguard Worker     EGLenum surfaceType(void) const;
347*35238bceSAndroid Build Coastguard Worker };
348*35238bceSAndroid Build Coastguard Worker 
surfaceType(void) const349*35238bceSAndroid Build Coastguard Worker EGLenum PreserveBackBufferCase::surfaceType(void) const
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker     return EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
352*35238bceSAndroid Build Coastguard Worker }
353*35238bceSAndroid Build Coastguard Worker 
iterate(void)354*35238bceSAndroid Build Coastguard Worker IterateResult PreserveBackBufferCase::iterate(void)
355*35238bceSAndroid Build Coastguard Worker {
356*35238bceSAndroid Build Coastguard Worker     const Library &egl = m_eglTestCtx.getLibrary();
357*35238bceSAndroid Build Coastguard Worker     ScopedCurrentContext currentCtx(egl, m_display, **m_surface, **m_surface, **m_context);
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker     EGLU_CHECK_CALL(egl, surfaceAttrib(m_display, **m_surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED));
360*35238bceSAndroid Build Coastguard Worker 
361*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(m_gl.getError(), "GL state erroneous upon initialization!");
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     {
364*35238bceSAndroid Build Coastguard Worker         const IVec2 oldEglSize = eglu::getSurfaceSize(egl, m_display, **m_surface);
365*35238bceSAndroid Build Coastguard Worker         initSurface(m_gl, oldEglSize);
366*35238bceSAndroid Build Coastguard Worker 
367*35238bceSAndroid Build Coastguard Worker         m_gl.finish();
368*35238bceSAndroid Build Coastguard Worker         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFinish() failed");
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         {
371*35238bceSAndroid Build Coastguard Worker             const Surface oldSurface = readSurface(m_gl, oldEglSize);
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker             egl.swapBuffers(m_display, **m_surface);
374*35238bceSAndroid Build Coastguard Worker             this->resize(m_newSize);
375*35238bceSAndroid Build Coastguard Worker             egl.swapBuffers(m_display, **m_surface);
376*35238bceSAndroid Build Coastguard Worker             EGLU_CHECK_MSG(egl, "eglSwapBuffers()");
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker             {
379*35238bceSAndroid Build Coastguard Worker                 const IVec2 newEglSize   = eglu::getSurfaceSize(egl, m_display, **m_surface);
380*35238bceSAndroid Build Coastguard Worker                 const Surface newSurface = readSurface(m_gl, newEglSize);
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker                 m_log << TestLog::ImageSet("Corner comparison", "Comparing old and new surfaces at all corners")
383*35238bceSAndroid Build Coastguard Worker                       << TestLog::Image("Before resizing", "Before resizing", oldSurface)
384*35238bceSAndroid Build Coastguard Worker                       << TestLog::Image("After resizing", "After resizing", newSurface) << TestLog::EndImageSet;
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker                 m_status.checkResult(compareCorners(oldSurface, newSurface), QP_TEST_RESULT_QUALITY_WARNING,
387*35238bceSAndroid Build Coastguard Worker                                      "Resizing the native window changed the contents of "
388*35238bceSAndroid Build Coastguard Worker                                      "the EGL surface");
389*35238bceSAndroid Build Coastguard Worker             }
390*35238bceSAndroid Build Coastguard Worker         }
391*35238bceSAndroid Build Coastguard Worker     }
392*35238bceSAndroid Build Coastguard Worker 
393*35238bceSAndroid Build Coastguard Worker     m_status.setTestContextResult(m_testCtx);
394*35238bceSAndroid Build Coastguard Worker     return STOP;
395*35238bceSAndroid Build Coastguard Worker }
396*35238bceSAndroid Build Coastguard Worker 
397*35238bceSAndroid Build Coastguard Worker typedef tcu::Vector<Interval, 2> IvVec2;
398*35238bceSAndroid Build Coastguard Worker 
399*35238bceSAndroid Build Coastguard Worker class UpdateResolutionCase : public ResizeTest
400*35238bceSAndroid Build Coastguard Worker {
401*35238bceSAndroid Build Coastguard Worker public:
UpdateResolutionCase(EglTestContext & eglTestCtx,const ResizeParams & params)402*35238bceSAndroid Build Coastguard Worker     UpdateResolutionCase(EglTestContext &eglTestCtx, const ResizeParams &params) : ResizeTest(eglTestCtx, params)
403*35238bceSAndroid Build Coastguard Worker     {
404*35238bceSAndroid Build Coastguard Worker     }
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker private:
409*35238bceSAndroid Build Coastguard Worker     IvVec2 getNativePixelsPerInch(void);
410*35238bceSAndroid Build Coastguard Worker };
411*35238bceSAndroid Build Coastguard Worker 
ivVec2(const IVec2 & vec)412*35238bceSAndroid Build Coastguard Worker IvVec2 ivVec2(const IVec2 &vec)
413*35238bceSAndroid Build Coastguard Worker {
414*35238bceSAndroid Build Coastguard Worker     return IvVec2(double(vec.x()), double(vec.y()));
415*35238bceSAndroid Build Coastguard Worker }
416*35238bceSAndroid Build Coastguard Worker 
approximateInt(int i)417*35238bceSAndroid Build Coastguard Worker Interval approximateInt(int i)
418*35238bceSAndroid Build Coastguard Worker {
419*35238bceSAndroid Build Coastguard Worker     const Interval margin(-1.0, 1.0); // The resolution may be rounded
420*35238bceSAndroid Build Coastguard Worker 
421*35238bceSAndroid Build Coastguard Worker     return (Interval(i) + margin) & Interval(0.0, TCU_INFINITY);
422*35238bceSAndroid Build Coastguard Worker }
423*35238bceSAndroid Build Coastguard Worker 
getNativePixelsPerInch(void)424*35238bceSAndroid Build Coastguard Worker IvVec2 UpdateResolutionCase::getNativePixelsPerInch(void)
425*35238bceSAndroid Build Coastguard Worker {
426*35238bceSAndroid Build Coastguard Worker     const Library &egl    = m_eglTestCtx.getLibrary();
427*35238bceSAndroid Build Coastguard Worker     const int inchPer10km = 254 * EGL_DISPLAY_SCALING;
428*35238bceSAndroid Build Coastguard Worker     const IVec2 bufSize   = eglu::getSurfaceSize(egl, m_display, **m_surface);
429*35238bceSAndroid Build Coastguard Worker     const IVec2 winSize   = m_nativeWindow->getScreenSize();
430*35238bceSAndroid Build Coastguard Worker     const IVec2 bufPp10km = eglu::getSurfaceResolution(egl, m_display, **m_surface);
431*35238bceSAndroid Build Coastguard Worker     const IvVec2 bufPpiI =
432*35238bceSAndroid Build Coastguard Worker         (IvVec2(approximateInt(bufPp10km.x()), approximateInt(bufPp10km.y())) / Interval(inchPer10km));
433*35238bceSAndroid Build Coastguard Worker     const IvVec2 winPpiI = ivVec2(winSize) * bufPpiI / ivVec2(bufSize);
434*35238bceSAndroid Build Coastguard Worker     const IVec2 winPpi(int(winPpiI.x().midpoint()), int(winPpiI.y().midpoint()));
435*35238bceSAndroid Build Coastguard Worker 
436*35238bceSAndroid Build Coastguard Worker     m_log << TestLog::Message << "EGL surface size: " << bufSize << "\n"
437*35238bceSAndroid Build Coastguard Worker           << "EGL surface pixel density (pixels / 10 km): " << bufPp10km << "\n"
438*35238bceSAndroid Build Coastguard Worker           << "Native window size: " << winSize << "\n"
439*35238bceSAndroid Build Coastguard Worker           << "Native pixel density (ppi): " << winPpi << "\n"
440*35238bceSAndroid Build Coastguard Worker           << TestLog::EndMessage;
441*35238bceSAndroid Build Coastguard Worker 
442*35238bceSAndroid Build Coastguard Worker     m_status.checkResult(bufPp10km.x() >= 1 && bufPp10km.y() >= 1, QP_TEST_RESULT_QUALITY_WARNING,
443*35238bceSAndroid Build Coastguard Worker                          "Surface pixel density is less than one pixel per 10 km. "
444*35238bceSAndroid Build Coastguard Worker                          "Is the surface really visible from space?");
445*35238bceSAndroid Build Coastguard Worker 
446*35238bceSAndroid Build Coastguard Worker     return winPpiI;
447*35238bceSAndroid Build Coastguard Worker }
448*35238bceSAndroid Build Coastguard Worker 
iterate(void)449*35238bceSAndroid Build Coastguard Worker IterateResult UpdateResolutionCase::iterate(void)
450*35238bceSAndroid Build Coastguard Worker {
451*35238bceSAndroid Build Coastguard Worker     const Library &egl = m_eglTestCtx.getLibrary();
452*35238bceSAndroid Build Coastguard Worker     ScopedCurrentContext currentCtx(egl, m_display, **m_surface, **m_surface, **m_context);
453*35238bceSAndroid Build Coastguard Worker 
454*35238bceSAndroid Build Coastguard Worker     if (!hasBits(m_nativeWindow->getCapabilities(), NativeWindow::CAPABILITY_GET_SCREEN_SIZE))
455*35238bceSAndroid Build Coastguard Worker         TCU_THROW(NotSupportedError, "Unable to determine surface size in screen pixels");
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker     {
458*35238bceSAndroid Build Coastguard Worker         const IVec2 oldEglSize = eglu::getSurfaceSize(egl, m_display, **m_surface);
459*35238bceSAndroid Build Coastguard Worker         initSurface(m_gl, oldEglSize);
460*35238bceSAndroid Build Coastguard Worker     }
461*35238bceSAndroid Build Coastguard Worker     {
462*35238bceSAndroid Build Coastguard Worker         const IvVec2 oldPpi = this->getNativePixelsPerInch();
463*35238bceSAndroid Build Coastguard Worker         this->resize(m_newSize);
464*35238bceSAndroid Build Coastguard Worker         EGLU_CHECK_CALL(egl, swapBuffers(m_display, **m_surface));
465*35238bceSAndroid Build Coastguard Worker         {
466*35238bceSAndroid Build Coastguard Worker             const IvVec2 newPpi = this->getNativePixelsPerInch();
467*35238bceSAndroid Build Coastguard Worker             m_status.check(oldPpi.x().intersects(newPpi.x()) && oldPpi.y().intersects(newPpi.y()),
468*35238bceSAndroid Build Coastguard Worker                            "Window PPI differs after resizing");
469*35238bceSAndroid Build Coastguard Worker         }
470*35238bceSAndroid Build Coastguard Worker     }
471*35238bceSAndroid Build Coastguard Worker 
472*35238bceSAndroid Build Coastguard Worker     m_status.setTestContextResult(m_testCtx);
473*35238bceSAndroid Build Coastguard Worker     return STOP;
474*35238bceSAndroid Build Coastguard Worker }
475*35238bceSAndroid Build Coastguard Worker 
ResizeTests(EglTestContext & eglTestCtx)476*35238bceSAndroid Build Coastguard Worker ResizeTests::ResizeTests(EglTestContext &eglTestCtx)
477*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(eglTestCtx, "resize", "Tests resizing the native surface")
478*35238bceSAndroid Build Coastguard Worker {
479*35238bceSAndroid Build Coastguard Worker }
480*35238bceSAndroid Build Coastguard Worker 
481*35238bceSAndroid Build Coastguard Worker template <class Case>
createCaseGroup(EglTestContext & eglTestCtx,const string & name,const string & desc)482*35238bceSAndroid Build Coastguard Worker TestCaseGroup *createCaseGroup(EglTestContext &eglTestCtx, const string &name, const string &desc)
483*35238bceSAndroid Build Coastguard Worker {
484*35238bceSAndroid Build Coastguard Worker     const ResizeParams params[] = {
485*35238bceSAndroid Build Coastguard Worker         {"shrink", "Shrink in both dimensions", IVec2(128, 128), IVec2(32, 32)},
486*35238bceSAndroid Build Coastguard Worker         {"grow", "Grow in both dimensions", IVec2(32, 32), IVec2(128, 128)},
487*35238bceSAndroid Build Coastguard Worker         {"stretch_width", "Grow horizontally, shrink vertically", IVec2(32, 128), IVec2(128, 32)},
488*35238bceSAndroid Build Coastguard Worker         {"stretch_height", "Grow vertically, shrink horizontally", IVec2(128, 32), IVec2(32, 128)},
489*35238bceSAndroid Build Coastguard Worker     };
490*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const group = new TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str());
491*35238bceSAndroid Build Coastguard Worker 
492*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(params); ++ndx)
493*35238bceSAndroid Build Coastguard Worker         group->addChild(new Case(eglTestCtx, params[ndx]));
494*35238bceSAndroid Build Coastguard Worker 
495*35238bceSAndroid Build Coastguard Worker     return group;
496*35238bceSAndroid Build Coastguard Worker }
497*35238bceSAndroid Build Coastguard Worker 
init(void)498*35238bceSAndroid Build Coastguard Worker void ResizeTests::init(void)
499*35238bceSAndroid Build Coastguard Worker {
500*35238bceSAndroid Build Coastguard Worker     addChild(createCaseGroup<ChangeSurfaceSizeCase>(m_eglTestCtx, "surface_size", "EGL surface size update"));
501*35238bceSAndroid Build Coastguard Worker     addChild(createCaseGroup<PreserveBackBufferCase>(m_eglTestCtx, "back_buffer", "Back buffer contents"));
502*35238bceSAndroid Build Coastguard Worker     addChild(createCaseGroup<UpdateResolutionCase>(m_eglTestCtx, "pixel_density", "Pixel density"));
503*35238bceSAndroid Build Coastguard Worker }
504*35238bceSAndroid Build Coastguard Worker 
505*35238bceSAndroid Build Coastguard Worker } // namespace egl
506*35238bceSAndroid Build Coastguard Worker } // namespace deqp
507