• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Surface.cpp: Implements the egl::Surface class, representing a drawing surface
8 // such as the client area of a window, including any back buffers.
9 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
10 
11 #include "libANGLE/Surface.h"
12 
13 #include <EGL/eglext.h>
14 
15 #include "libANGLE/Config.h"
16 #include "libANGLE/Context.h"
17 #include "libANGLE/Display.h"
18 #include "libANGLE/Framebuffer.h"
19 #include "libANGLE/Texture.h"
20 #include "libANGLE/Thread.h"
21 #include "libANGLE/formatutils.h"
22 #include "libANGLE/renderer/EGLImplFactory.h"
23 #include "libANGLE/trace.h"
24 
25 namespace egl
26 {
27 
SurfaceState(const egl::Config * configIn,const AttributeMap & attributesIn)28 SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
29     : label(nullptr),
30       config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr),
31       attributes(attributesIn),
32       timestampsEnabled(false),
33       directComposition(false)
34 {
35     directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE;
36 }
37 
~SurfaceState()38 SurfaceState::~SurfaceState()
39 {
40     delete config;
41 }
42 
Surface(EGLint surfaceType,const egl::Config * config,const AttributeMap & attributes,EGLenum buftype)43 Surface::Surface(EGLint surfaceType,
44                  const egl::Config *config,
45                  const AttributeMap &attributes,
46                  EGLenum buftype)
47     : FramebufferAttachmentObject(),
48       mState(config, attributes),
49       mImplementation(nullptr),
50       mRefCount(0),
51       mDestroyed(false),
52       mType(surfaceType),
53       mBuftype(buftype),
54       mPostSubBufferRequested(false),
55       mLargestPbuffer(false),
56       mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
57       mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
58       mVGColorspace(EGL_VG_COLORSPACE_sRGB),
59       mMipmapTexture(false),
60       mMipmapLevel(0),
61       mHorizontalResolution(EGL_UNKNOWN),
62       mVerticalResolution(EGL_UNKNOWN),
63       mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
64       mFixedSize(false),
65       mFixedWidth(0),
66       mFixedHeight(0),
67       mTextureFormat(TextureFormat::NoTexture),
68       mTextureTarget(EGL_NO_TEXTURE),
69       // FIXME: Determine actual pixel aspect ratio
70       mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
71       mRenderBuffer(EGL_BACK_BUFFER),
72       mSwapBehavior(EGL_NONE),
73       mOrientation(0),
74       mTexture(nullptr),
75       mColorFormat(config->renderTargetFormat),
76       mDSFormat(config->depthStencilFormat),
77       mInitState(gl::InitState::Initialized)
78 {
79     mPostSubBufferRequested =
80         (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
81     mFlexibleSurfaceCompatibilityRequested =
82         (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE);
83 
84     if (mType == EGL_PBUFFER_BIT)
85     {
86         mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
87     }
88 
89     mGLColorspace =
90         static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
91     mVGAlphaFormat =
92         static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
93     mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
94     mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);
95 
96     mRobustResourceInitialization =
97         (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
98     if (mRobustResourceInitialization)
99     {
100         mInitState = gl::InitState::MayNeedInit;
101     }
102 
103     mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
104     if (mFixedSize)
105     {
106         mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
107         mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
108     }
109 
110     if (mType != EGL_WINDOW_BIT)
111     {
112         mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
113         mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
114     }
115 
116     mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));
117 }
118 
~Surface()119 Surface::~Surface() {}
120 
getAttachmentImpl() const121 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
122 {
123     return mImplementation;
124 }
125 
destroyImpl(const Display * display)126 Error Surface::destroyImpl(const Display *display)
127 {
128     if (mImplementation)
129     {
130         mImplementation->destroy(display);
131     }
132 
133     ASSERT(!mTexture);
134 
135     SafeDelete(mImplementation);
136 
137     delete this;
138     return NoError();
139 }
140 
postSwap(const gl::Context * context)141 void Surface::postSwap(const gl::Context *context)
142 {
143     if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
144     {
145         mInitState = gl::InitState::MayNeedInit;
146         onStateChange(angle::SubjectMessage::SubjectChanged);
147     }
148 
149     context->onPostSwap();
150 }
151 
initialize(const Display * display)152 Error Surface::initialize(const Display *display)
153 {
154     GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;
155 
156     // To account for color space differences, override the renderTargetFormat with the
157     // non-linear format. If no suitable non-linear format was found, return
158     // EGL_BAD_MATCH error
159     if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
160     {
161         return egl::EglBadMatch();
162     }
163 
164     // If an override is required update mState.config as well
165     if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
166     {
167         egl::Config *overrideConfig        = new egl::Config(*(mState.config));
168         overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
169         delete mState.config;
170         mState.config = overrideConfig;
171 
172         mColorFormat = gl::Format(mState.config->renderTargetFormat);
173         mDSFormat    = gl::Format(mState.config->depthStencilFormat);
174     }
175 
176     ANGLE_TRY(mImplementation->initialize(display));
177 
178     // Initialized here since impl is nullptr in the constructor.
179     // Must happen after implementation initialize for Android.
180     mSwapBehavior = mImplementation->getSwapBehavior();
181 
182     if (mBuftype == EGL_IOSURFACE_ANGLE)
183     {
184         GLenum internalFormat =
185             static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
186         GLenum type  = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));
187         mColorFormat = gl::Format(internalFormat, type);
188     }
189     if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
190     {
191         const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat();
192         ASSERT(colorFormat != nullptr);
193         GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
194         mColorFormat          = gl::Format(internalFormat, colorFormat->componentType);
195         mGLColorspace         = EGL_GL_COLORSPACE_LINEAR;
196         if (mColorFormat.info->colorEncoding == GL_SRGB)
197         {
198             mGLColorspace = EGL_GL_COLORSPACE_SRGB;
199         }
200     }
201 
202     if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
203     {
204         mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
205         mState.supportedTimestamps        = mImplementation->getSupportedTimestamps();
206     }
207 
208     return NoError();
209 }
210 
makeCurrent(const gl::Context * context)211 Error Surface::makeCurrent(const gl::Context *context)
212 {
213     ANGLE_TRY(mImplementation->makeCurrent(context));
214 
215     mRefCount++;
216     return NoError();
217 }
218 
unMakeCurrent(const gl::Context * context)219 Error Surface::unMakeCurrent(const gl::Context *context)
220 {
221     ANGLE_TRY(mImplementation->unMakeCurrent(context));
222     return releaseRef(context->getDisplay());
223 }
224 
releaseRef(const Display * display)225 Error Surface::releaseRef(const Display *display)
226 {
227     ASSERT(mRefCount > 0);
228     mRefCount--;
229     if (mRefCount == 0 && mDestroyed)
230     {
231         ASSERT(display);
232         return destroyImpl(display);
233     }
234 
235     return NoError();
236 }
237 
onDestroy(const Display * display)238 Error Surface::onDestroy(const Display *display)
239 {
240     mDestroyed = true;
241     if (mRefCount == 0)
242     {
243         return destroyImpl(display);
244     }
245     return NoError();
246 }
247 
setLabel(EGLLabelKHR label)248 void Surface::setLabel(EGLLabelKHR label)
249 {
250     mState.label = label;
251 }
252 
getLabel() const253 EGLLabelKHR Surface::getLabel() const
254 {
255     return mState.label;
256 }
257 
getType() const258 EGLint Surface::getType() const
259 {
260     return mType;
261 }
262 
swap(const gl::Context * context)263 Error Surface::swap(const gl::Context *context)
264 {
265     ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
266 
267     context->getState().getOverlay()->onSwap();
268 
269     ANGLE_TRY(mImplementation->swap(context));
270     postSwap(context);
271     return NoError();
272 }
273 
swapWithDamage(const gl::Context * context,EGLint * rects,EGLint n_rects)274 Error Surface::swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects)
275 {
276     context->getState().getOverlay()->onSwap();
277 
278     ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects));
279     postSwap(context);
280     return NoError();
281 }
282 
swapWithFrameToken(const gl::Context * context,EGLFrameTokenANGLE frameToken)283 Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken)
284 {
285     context->getState().getOverlay()->onSwap();
286 
287     ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken));
288     postSwap(context);
289     return NoError();
290 }
291 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)292 Error Surface::postSubBuffer(const gl::Context *context,
293                              EGLint x,
294                              EGLint y,
295                              EGLint width,
296                              EGLint height)
297 {
298     if (width == 0 || height == 0)
299     {
300         return egl::NoError();
301     }
302 
303     context->getState().getOverlay()->onSwap();
304 
305     ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
306     postSwap(context);
307     return NoError();
308 }
309 
setPresentationTime(EGLnsecsANDROID time)310 Error Surface::setPresentationTime(EGLnsecsANDROID time)
311 {
312     return mImplementation->setPresentationTime(time);
313 }
314 
querySurfacePointerANGLE(EGLint attribute,void ** value)315 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
316 {
317     return mImplementation->querySurfacePointerANGLE(attribute, value);
318 }
319 
isPostSubBufferSupported() const320 EGLint Surface::isPostSubBufferSupported() const
321 {
322     return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
323 }
324 
setSwapInterval(EGLint interval)325 void Surface::setSwapInterval(EGLint interval)
326 {
327     mImplementation->setSwapInterval(interval);
328 }
329 
setMipmapLevel(EGLint level)330 void Surface::setMipmapLevel(EGLint level)
331 {
332     // Level is set but ignored
333     UNIMPLEMENTED();
334     mMipmapLevel = level;
335 }
336 
setMultisampleResolve(EGLenum resolve)337 void Surface::setMultisampleResolve(EGLenum resolve)
338 {
339     // Behaviour is set but ignored
340     UNIMPLEMENTED();
341     mMultisampleResolve = resolve;
342 }
343 
setSwapBehavior(EGLenum behavior)344 void Surface::setSwapBehavior(EGLenum behavior)
345 {
346     // Behaviour is set but ignored
347     UNIMPLEMENTED();
348     mSwapBehavior = behavior;
349 }
350 
setFixedWidth(EGLint width)351 void Surface::setFixedWidth(EGLint width)
352 {
353     mFixedWidth = width;
354     mImplementation->setFixedWidth(width);
355 }
356 
setFixedHeight(EGLint height)357 void Surface::setFixedHeight(EGLint height)
358 {
359     mFixedHeight = height;
360     mImplementation->setFixedHeight(height);
361 }
362 
getConfig() const363 const Config *Surface::getConfig() const
364 {
365     return mState.config;
366 }
367 
getPixelAspectRatio() const368 EGLint Surface::getPixelAspectRatio() const
369 {
370     return mPixelAspectRatio;
371 }
372 
getRenderBuffer() const373 EGLenum Surface::getRenderBuffer() const
374 {
375     return mRenderBuffer;
376 }
377 
getSwapBehavior() const378 EGLenum Surface::getSwapBehavior() const
379 {
380     return mSwapBehavior;
381 }
382 
getTextureFormat() const383 TextureFormat Surface::getTextureFormat() const
384 {
385     return mTextureFormat;
386 }
387 
getTextureTarget() const388 EGLenum Surface::getTextureTarget() const
389 {
390     return mTextureTarget;
391 }
392 
getLargestPbuffer() const393 bool Surface::getLargestPbuffer() const
394 {
395     return mLargestPbuffer;
396 }
397 
getGLColorspace() const398 EGLenum Surface::getGLColorspace() const
399 {
400     return mGLColorspace;
401 }
402 
getVGAlphaFormat() const403 EGLenum Surface::getVGAlphaFormat() const
404 {
405     return mVGAlphaFormat;
406 }
407 
getVGColorspace() const408 EGLenum Surface::getVGColorspace() const
409 {
410     return mVGColorspace;
411 }
412 
getMipmapTexture() const413 bool Surface::getMipmapTexture() const
414 {
415     return mMipmapTexture;
416 }
417 
getMipmapLevel() const418 EGLint Surface::getMipmapLevel() const
419 {
420     return mMipmapLevel;
421 }
422 
getHorizontalResolution() const423 EGLint Surface::getHorizontalResolution() const
424 {
425     return mHorizontalResolution;
426 }
427 
getVerticalResolution() const428 EGLint Surface::getVerticalResolution() const
429 {
430     return mVerticalResolution;
431 }
432 
getMultisampleResolve() const433 EGLenum Surface::getMultisampleResolve() const
434 {
435     return mMultisampleResolve;
436 }
437 
isFixedSize() const438 EGLint Surface::isFixedSize() const
439 {
440     return mFixedSize;
441 }
442 
getWidth() const443 EGLint Surface::getWidth() const
444 {
445     return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth();
446 }
447 
getHeight() const448 EGLint Surface::getHeight() const
449 {
450     return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight();
451 }
452 
bindTexImage(gl::Context * context,gl::Texture * texture,EGLint buffer)453 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
454 {
455     ASSERT(!mTexture);
456     ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
457 
458     if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
459     {
460         return Error(EGL_BAD_SURFACE);
461     }
462     mTexture = texture;
463     mRefCount++;
464 
465     return NoError();
466 }
467 
releaseTexImage(const gl::Context * context,EGLint buffer)468 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
469 {
470     ASSERT(context);
471 
472     ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));
473 
474     ASSERT(mTexture);
475     ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));
476 
477     return releaseTexImageFromTexture(context);
478 }
479 
getSyncValues(EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)480 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
481 {
482     return mImplementation->getSyncValues(ust, msc, sbc);
483 }
484 
getMscRate(EGLint * numerator,EGLint * denominator)485 Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
486 {
487     return mImplementation->getMscRate(numerator, denominator);
488 }
489 
releaseTexImageFromTexture(const gl::Context * context)490 Error Surface::releaseTexImageFromTexture(const gl::Context *context)
491 {
492     ASSERT(mTexture);
493     mTexture = nullptr;
494     return releaseRef(context->getDisplay());
495 }
496 
getAttachmentSize(const gl::ImageIndex &) const497 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
498 {
499     return gl::Extents(getWidth(), getHeight(), 1);
500 }
501 
getAttachmentFormat(GLenum binding,const gl::ImageIndex & target) const502 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
503 {
504     return (binding == GL_BACK ? mColorFormat : mDSFormat);
505 }
506 
getAttachmentSamples(const gl::ImageIndex & target) const507 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
508 {
509     return getConfig()->samples;
510 }
511 
isRenderable(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex) const512 bool Surface::isRenderable(const gl::Context *context,
513                            GLenum binding,
514                            const gl::ImageIndex &imageIndex) const
515 {
516     return true;
517 }
518 
getId() const519 GLuint Surface::getId() const
520 {
521     UNREACHABLE();
522     return 0;
523 }
524 
createDefaultFramebuffer(const gl::Context * context,egl::Surface * readSurface)525 gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context,
526                                                    egl::Surface *readSurface)
527 {
528     return new gl::Framebuffer(context, this, readSurface);
529 }
530 
initState(const gl::ImageIndex &) const531 gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
532 {
533     return mInitState;
534 }
535 
setInitState(const gl::ImageIndex &,gl::InitState initState)536 void Surface::setInitState(const gl::ImageIndex & /*imageIndex*/, gl::InitState initState)
537 {
538     mInitState = initState;
539 }
540 
setTimestampsEnabled(bool enabled)541 void Surface::setTimestampsEnabled(bool enabled)
542 {
543     mImplementation->setTimestampsEnabled(enabled);
544     mState.timestampsEnabled = enabled;
545 }
546 
isTimestampsEnabled() const547 bool Surface::isTimestampsEnabled() const
548 {
549     return mState.timestampsEnabled;
550 }
551 
getSupportedCompositorTimings() const552 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
553 {
554     return mState.supportedCompositorTimings;
555 }
556 
getCompositorTiming(EGLint numTimestamps,const EGLint * names,EGLnsecsANDROID * values) const557 Error Surface::getCompositorTiming(EGLint numTimestamps,
558                                    const EGLint *names,
559                                    EGLnsecsANDROID *values) const
560 {
561     return mImplementation->getCompositorTiming(numTimestamps, names, values);
562 }
563 
getNextFrameId(EGLuint64KHR * frameId) const564 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
565 {
566     return mImplementation->getNextFrameId(frameId);
567 }
568 
getSupportedTimestamps() const569 const SupportedTimestamps &Surface::getSupportedTimestamps() const
570 {
571     return mState.supportedTimestamps;
572 }
573 
getFrameTimestamps(EGLuint64KHR frameId,EGLint numTimestamps,const EGLint * timestamps,EGLnsecsANDROID * values) const574 Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
575                                   EGLint numTimestamps,
576                                   const EGLint *timestamps,
577                                   EGLnsecsANDROID *values) const
578 {
579     return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
580 }
581 
WindowSurface(rx::EGLImplFactory * implFactory,const egl::Config * config,EGLNativeWindowType window,const AttributeMap & attribs)582 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
583                              const egl::Config *config,
584                              EGLNativeWindowType window,
585                              const AttributeMap &attribs)
586     : Surface(EGL_WINDOW_BIT, config, attribs)
587 {
588     mImplementation = implFactory->createWindowSurface(mState, window, attribs);
589 }
590 
~WindowSurface()591 WindowSurface::~WindowSurface() {}
592 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,const AttributeMap & attribs)593 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
594                                const Config *config,
595                                const AttributeMap &attribs)
596     : Surface(EGL_PBUFFER_BIT, config, attribs)
597 {
598     mImplementation = implFactory->createPbufferSurface(mState, attribs);
599 }
600 
PbufferSurface(rx::EGLImplFactory * implFactory,const Config * config,EGLenum buftype,EGLClientBuffer clientBuffer,const AttributeMap & attribs)601 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
602                                const Config *config,
603                                EGLenum buftype,
604                                EGLClientBuffer clientBuffer,
605                                const AttributeMap &attribs)
606     : Surface(EGL_PBUFFER_BIT, config, attribs, buftype)
607 {
608     mImplementation =
609         implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
610 }
611 
~PbufferSurface()612 PbufferSurface::~PbufferSurface() {}
613 
PixmapSurface(rx::EGLImplFactory * implFactory,const Config * config,NativePixmapType nativePixmap,const AttributeMap & attribs)614 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
615                              const Config *config,
616                              NativePixmapType nativePixmap,
617                              const AttributeMap &attribs)
618     : Surface(EGL_PIXMAP_BIT, config, attribs)
619 {
620     mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
621 }
622 
~PixmapSurface()623 PixmapSurface::~PixmapSurface() {}
624 
625 // SurfaceDeleter implementation.
626 
SurfaceDeleter(const Display * display)627 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}
628 
~SurfaceDeleter()629 SurfaceDeleter::~SurfaceDeleter() {}
630 
operator ()(Surface * surface)631 void SurfaceDeleter::operator()(Surface *surface)
632 {
633     ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
634 }
635 
636 }  // namespace egl
637