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