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