Surface.cpp (25477B)
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/formatutils.h" 21 #include "libANGLE/renderer/EGLImplFactory.h" 22 #include "libANGLE/trace.h" 23 24 namespace egl 25 { 26 namespace 27 { 28 angle::SubjectIndex kSurfaceImplSubjectIndex = 0; 29 } // namespace 30 31 SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn) 32 : label(nullptr), 33 config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr), 34 attributes(attributesIn), 35 timestampsEnabled(false), 36 autoRefreshEnabled(false), 37 directComposition(false), 38 swapBehavior(EGL_NONE) 39 { 40 directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE; 41 } 42 43 SurfaceState::~SurfaceState() 44 { 45 delete config; 46 } 47 48 bool SurfaceState::isRobustResourceInitEnabled() const 49 { 50 return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE; 51 } 52 53 bool SurfaceState::hasProtectedContent() const 54 { 55 return attributes.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE; 56 } 57 58 EGLint SurfaceState::getPreferredSwapInterval() const 59 { 60 return attributes.getAsInt(EGL_SWAP_INTERVAL_ANGLE, 1); 61 } 62 63 Surface::Surface(EGLint surfaceType, 64 GLuint serialId, 65 const egl::Config *config, 66 const AttributeMap &attributes, 67 bool forceRobustResourceInit, 68 EGLenum buftype) 69 : FramebufferAttachmentObject(), 70 mState(config, attributes), 71 mImplementation(nullptr), 72 mRefCount(0), 73 mDestroyed(false), 74 mType(surfaceType), 75 mBuftype(buftype), 76 mPostSubBufferRequested(false), 77 mLargestPbuffer(false), 78 mGLColorspace(EGL_GL_COLORSPACE_LINEAR), 79 mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE), 80 mVGColorspace(EGL_VG_COLORSPACE_sRGB), 81 mMipmapTexture(false), 82 mMipmapLevel(0), 83 mHorizontalResolution(EGL_UNKNOWN), 84 mVerticalResolution(EGL_UNKNOWN), 85 mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT), 86 mFixedSize(false), 87 mFixedWidth(0), 88 mFixedHeight(0), 89 mTextureFormat(TextureFormat::NoTexture), 90 mTextureTarget(EGL_NO_TEXTURE), 91 // FIXME: Determine actual pixel aspect ratio 92 mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)), 93 mRenderBuffer(EGL_BACK_BUFFER), 94 mOrientation(0), 95 mTexture(nullptr), 96 mColorFormat(config->renderTargetFormat), 97 mDSFormat(config->depthStencilFormat), 98 mIsCurrentOnAnyContext(false), 99 mLockBufferPtr(nullptr), 100 mLockBufferPitch(0), 101 mBufferAgeQueriedSinceLastSwap(false), 102 mIsDamageRegionSet(false), 103 mColorInitState(gl::InitState::Initialized), 104 mDepthStencilInitState(gl::InitState::Initialized), 105 mImplObserverBinding(this, kSurfaceImplSubjectIndex), 106 mSerialId(serialId) 107 { 108 mPostSubBufferRequested = 109 (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); 110 111 if (mType == EGL_PBUFFER_BIT) 112 { 113 mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE); 114 } 115 116 if (mType == EGL_PIXMAP_BIT) 117 { 118 mRenderBuffer = EGL_SINGLE_BUFFER; 119 } 120 121 if (mType == EGL_WINDOW_BIT) 122 { 123 mRenderBuffer = mState.attributes.getAsInt(EGL_RENDER_BUFFER, EGL_BACK_BUFFER); 124 } 125 126 mGLColorspace = 127 static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR)); 128 mVGAlphaFormat = 129 static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE)); 130 mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB)); 131 mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE); 132 133 mRobustResourceInitialization = 134 forceRobustResourceInit || 135 (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE); 136 if (mRobustResourceInitialization) 137 { 138 mColorInitState = gl::InitState::MayNeedInit; 139 mDepthStencilInitState = gl::InitState::MayNeedInit; 140 } 141 142 mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE); 143 if (mFixedSize) 144 { 145 mFixedWidth = static_cast<size_t>(attributes.get(EGL_WIDTH, 0)); 146 mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0)); 147 } 148 149 if (mType != EGL_WINDOW_BIT) 150 { 151 mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture); 152 mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); 153 } 154 155 mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); 156 157 mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0)); 158 mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0)); 159 } 160 161 Surface::~Surface() {} 162 163 rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const 164 { 165 return mImplementation; 166 } 167 168 Error Surface::destroyImpl(const Display *display) 169 { 170 if (mImplementation) 171 { 172 mImplementation->destroy(display); 173 } 174 175 ASSERT(!mTexture); 176 177 SafeDelete(mImplementation); 178 179 delete this; 180 return NoError(); 181 } 182 183 void Surface::postSwap(const gl::Context *context) 184 { 185 if (mRobustResourceInitialization && mState.swapBehavior != EGL_BUFFER_PRESERVED) 186 { 187 mColorInitState = gl::InitState::MayNeedInit; 188 mDepthStencilInitState = gl::InitState::MayNeedInit; 189 onStateChange(angle::SubjectMessage::SubjectChanged); 190 } 191 192 mBufferAgeQueriedSinceLastSwap = false; 193 194 mIsDamageRegionSet = false; 195 } 196 197 Error Surface::initialize(const Display *display) 198 { 199 GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat; 200 201 // To account for color space differences, override the renderTargetFormat with the 202 // non-linear format. If no suitable non-linear format was found, return 203 // EGL_BAD_MATCH error 204 if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat)) 205 { 206 return egl::EglBadMatch(); 207 } 208 209 // If an override is required update mState.config as well 210 if (mState.config->renderTargetFormat != overrideRenderTargetFormat) 211 { 212 egl::Config *overrideConfig = new egl::Config(*(mState.config)); 213 overrideConfig->renderTargetFormat = overrideRenderTargetFormat; 214 delete mState.config; 215 mState.config = overrideConfig; 216 217 mColorFormat = gl::Format(mState.config->renderTargetFormat); 218 mDSFormat = gl::Format(mState.config->depthStencilFormat); 219 } 220 221 ANGLE_TRY(mImplementation->initialize(display)); 222 223 // Initialized here since impl is nullptr in the constructor. 224 // Must happen after implementation initialize for Android. 225 mState.swapBehavior = mImplementation->getSwapBehavior(); 226 227 if (mBuftype == EGL_IOSURFACE_ANGLE) 228 { 229 GLenum internalFormat = 230 static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE)); 231 GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE)); 232 233 // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in 234 // desktop GL. Adjust the frontend format to be sized RGBA16F. 235 if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT) 236 { 237 internalFormat = GL_RGBA16F; 238 } 239 mColorFormat = gl::Format(internalFormat, type); 240 } 241 if (mBuftype == EGL_D3D_TEXTURE_ANGLE) 242 { 243 const angle::Format *colorFormat = mImplementation->getD3DTextureColorFormat(); 244 ASSERT(colorFormat != nullptr); 245 GLenum internalFormat = colorFormat->fboImplementationInternalFormat; 246 mColorFormat = gl::Format(internalFormat, colorFormat->componentType); 247 mGLColorspace = EGL_GL_COLORSPACE_LINEAR; 248 if (mColorFormat.info->colorEncoding == GL_SRGB) 249 { 250 mGLColorspace = EGL_GL_COLORSPACE_SRGB; 251 } 252 } 253 254 if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps) 255 { 256 mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings(); 257 mState.supportedTimestamps = mImplementation->getSupportedTimestamps(); 258 } 259 260 mImplObserverBinding.bind(mImplementation); 261 262 return NoError(); 263 } 264 265 Error Surface::makeCurrent(const gl::Context *context) 266 { 267 if (isLocked()) 268 { 269 return EglBadAccess(); 270 } 271 ANGLE_TRY(mImplementation->makeCurrent(context)); 272 mIsCurrentOnAnyContext = true; 273 addRef(); 274 return NoError(); 275 } 276 277 Error Surface::unMakeCurrent(const gl::Context *context) 278 { 279 ANGLE_TRY(mImplementation->unMakeCurrent(context)); 280 mIsCurrentOnAnyContext = false; 281 return releaseRef(context->getDisplay()); 282 } 283 284 Error Surface::releaseRef(const Display *display) 285 { 286 ASSERT(mRefCount > 0); 287 mRefCount--; 288 if (mRefCount == 0 && mDestroyed) 289 { 290 ASSERT(display); 291 return destroyImpl(display); 292 } 293 294 return NoError(); 295 } 296 297 Error Surface::onDestroy(const Display *display) 298 { 299 mDestroyed = true; 300 if (mRefCount == 0) 301 { 302 return destroyImpl(display); 303 } 304 return NoError(); 305 } 306 307 void Surface::setLabel(EGLLabelKHR label) 308 { 309 mState.label = label; 310 } 311 312 EGLLabelKHR Surface::getLabel() const 313 { 314 return mState.label; 315 } 316 317 EGLint Surface::getType() const 318 { 319 return mType; 320 } 321 322 Error Surface::prepareSwap(const gl::Context *context) 323 { 324 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::prepareSwap"); 325 return mImplementation->prepareSwap(context); 326 } 327 328 Error Surface::swap(const gl::Context *context) 329 { 330 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap"); 331 context->onPreSwap(); 332 333 context->getState().getOverlay()->onSwap(); 334 335 ANGLE_TRY(mImplementation->swap(context)); 336 postSwap(context); 337 return NoError(); 338 } 339 340 Error Surface::swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects) 341 { 342 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage"); 343 context->onPreSwap(); 344 345 context->getState().getOverlay()->onSwap(); 346 347 ANGLE_TRY(mImplementation->swapWithDamage(context, rects, n_rects)); 348 postSwap(context); 349 return NoError(); 350 } 351 352 Error Surface::swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken) 353 { 354 ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithFrameToken"); 355 context->onPreSwap(); 356 357 context->getState().getOverlay()->onSwap(); 358 359 ANGLE_TRY(mImplementation->swapWithFrameToken(context, frameToken)); 360 postSwap(context); 361 return NoError(); 362 } 363 364 Error Surface::postSubBuffer(const gl::Context *context, 365 EGLint x, 366 EGLint y, 367 EGLint width, 368 EGLint height) 369 { 370 if (width == 0 || height == 0) 371 { 372 return egl::NoError(); 373 } 374 375 context->getState().getOverlay()->onSwap(); 376 377 ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height)); 378 postSwap(context); 379 return NoError(); 380 } 381 382 Error Surface::setPresentationTime(EGLnsecsANDROID time) 383 { 384 return mImplementation->setPresentationTime(time); 385 } 386 387 Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value) 388 { 389 return mImplementation->querySurfacePointerANGLE(attribute, value); 390 } 391 392 EGLint Surface::isPostSubBufferSupported() const 393 { 394 return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported(); 395 } 396 397 void Surface::setSwapInterval(EGLint interval) 398 { 399 mImplementation->setSwapInterval(interval); 400 } 401 402 void Surface::setMipmapLevel(EGLint level) 403 { 404 // Level is set but ignored 405 UNIMPLEMENTED(); 406 mMipmapLevel = level; 407 } 408 409 void Surface::setMultisampleResolve(EGLenum resolve) 410 { 411 // Behaviour is set but ignored 412 UNIMPLEMENTED(); 413 mMultisampleResolve = resolve; 414 } 415 416 void Surface::setSwapBehavior(EGLenum behavior) 417 { 418 // Behaviour is set but ignored 419 UNIMPLEMENTED(); 420 mState.swapBehavior = behavior; 421 } 422 423 void Surface::setFixedWidth(EGLint width) 424 { 425 mFixedWidth = width; 426 mImplementation->setFixedWidth(width); 427 } 428 429 void Surface::setFixedHeight(EGLint height) 430 { 431 mFixedHeight = height; 432 mImplementation->setFixedHeight(height); 433 } 434 435 const Config *Surface::getConfig() const 436 { 437 return mState.config; 438 } 439 440 EGLint Surface::getPixelAspectRatio() const 441 { 442 return mPixelAspectRatio; 443 } 444 445 EGLenum Surface::getRenderBuffer() const 446 { 447 return mRenderBuffer; 448 } 449 450 EGLenum Surface::getSwapBehavior() const 451 { 452 return mState.swapBehavior; 453 } 454 455 TextureFormat Surface::getTextureFormat() const 456 { 457 return mTextureFormat; 458 } 459 460 EGLenum Surface::getTextureTarget() const 461 { 462 return mTextureTarget; 463 } 464 465 bool Surface::getLargestPbuffer() const 466 { 467 return mLargestPbuffer; 468 } 469 470 EGLenum Surface::getGLColorspace() const 471 { 472 return mGLColorspace; 473 } 474 475 EGLenum Surface::getVGAlphaFormat() const 476 { 477 return mVGAlphaFormat; 478 } 479 480 EGLenum Surface::getVGColorspace() const 481 { 482 return mVGColorspace; 483 } 484 485 bool Surface::getMipmapTexture() const 486 { 487 return mMipmapTexture; 488 } 489 490 EGLint Surface::getMipmapLevel() const 491 { 492 return mMipmapLevel; 493 } 494 495 EGLint Surface::getHorizontalResolution() const 496 { 497 return mHorizontalResolution; 498 } 499 500 EGLint Surface::getVerticalResolution() const 501 { 502 return mVerticalResolution; 503 } 504 505 EGLenum Surface::getMultisampleResolve() const 506 { 507 return mMultisampleResolve; 508 } 509 510 EGLint Surface::isFixedSize() const 511 { 512 return mFixedSize; 513 } 514 515 EGLint Surface::getWidth() const 516 { 517 return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth(); 518 } 519 520 EGLint Surface::getHeight() const 521 { 522 return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight(); 523 } 524 525 egl::Error Surface::getUserWidth(const egl::Display *display, EGLint *value) const 526 { 527 if (mFixedSize) 528 { 529 *value = static_cast<EGLint>(mFixedWidth); 530 return NoError(); 531 } 532 else 533 { 534 return mImplementation->getUserWidth(display, value); 535 } 536 } 537 538 egl::Error Surface::getUserHeight(const egl::Display *display, EGLint *value) const 539 { 540 if (mFixedSize) 541 { 542 *value = static_cast<EGLint>(mFixedHeight); 543 return NoError(); 544 } 545 else 546 { 547 return mImplementation->getUserHeight(display, value); 548 } 549 } 550 551 Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer) 552 { 553 ASSERT(!mTexture); 554 ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer)); 555 556 if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop) 557 { 558 return Error(EGL_BAD_SURFACE); 559 } 560 mTexture = texture; 561 addRef(); 562 563 return NoError(); 564 } 565 566 Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer) 567 { 568 ASSERT(context); 569 570 ANGLE_TRY(mImplementation->releaseTexImage(context, buffer)); 571 572 ASSERT(mTexture); 573 ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context))); 574 575 return releaseTexImageFromTexture(context); 576 } 577 578 Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) 579 { 580 return mImplementation->getSyncValues(ust, msc, sbc); 581 } 582 583 Error Surface::getMscRate(EGLint *numerator, EGLint *denominator) 584 { 585 return mImplementation->getMscRate(numerator, denominator); 586 } 587 588 Error Surface::releaseTexImageFromTexture(const gl::Context *context) 589 { 590 ASSERT(mTexture); 591 mTexture = nullptr; 592 return releaseRef(context->getDisplay()); 593 } 594 595 gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const 596 { 597 return gl::Extents(getWidth(), getHeight(), 1); 598 } 599 600 gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const 601 { 602 return (binding == GL_BACK ? mColorFormat : mDSFormat); 603 } 604 605 GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const 606 { 607 return getConfig()->samples; 608 } 609 610 bool Surface::isRenderable(const gl::Context *context, 611 GLenum binding, 612 const gl::ImageIndex &imageIndex) const 613 { 614 return true; 615 } 616 617 bool Surface::isYUV() const 618 { 619 // EGL_EXT_yuv_surface is not implemented. 620 return false; 621 } 622 623 bool Surface::isCreatedWithAHB() const 624 { 625 return false; 626 } 627 628 GLuint Surface::getId() const 629 { 630 return mSerialId; 631 } 632 633 Error Surface::getBufferAgeImpl(const gl::Context *context, EGLint *age) const 634 { 635 // When EGL_BUFFER_PRESERVED, the previous frame contents are copied to 636 // current frame, so the buffer age is always 1. 637 if (mState.swapBehavior == EGL_BUFFER_PRESERVED) 638 { 639 if (age != nullptr) 640 { 641 *age = 1; 642 } 643 return egl::NoError(); 644 } 645 return mImplementation->getBufferAge(context, age); 646 } 647 648 Error Surface::getBufferAge(const gl::Context *context, EGLint *age) 649 { 650 Error err = getBufferAgeImpl(context, age); 651 if (!err.isError()) 652 { 653 mBufferAgeQueriedSinceLastSwap = true; 654 } 655 return err; 656 } 657 658 gl::InitState Surface::initState(GLenum binding, const gl::ImageIndex & /*imageIndex*/) const 659 { 660 switch (binding) 661 { 662 case GL_BACK: 663 return mColorInitState; 664 case GL_DEPTH: 665 case GL_STENCIL: 666 return mDepthStencilInitState; 667 default: 668 UNREACHABLE(); 669 return gl::InitState::Initialized; 670 } 671 } 672 673 void Surface::setInitState(GLenum binding, 674 const gl::ImageIndex & /*imageIndex*/, 675 gl::InitState initState) 676 { 677 switch (binding) 678 { 679 case GL_BACK: 680 mColorInitState = initState; 681 break; 682 case GL_DEPTH: 683 case GL_STENCIL: 684 mDepthStencilInitState = initState; 685 break; 686 default: 687 UNREACHABLE(); 688 break; 689 } 690 } 691 692 void Surface::setTimestampsEnabled(bool enabled) 693 { 694 mImplementation->setTimestampsEnabled(enabled); 695 mState.timestampsEnabled = enabled; 696 } 697 698 bool Surface::isTimestampsEnabled() const 699 { 700 return mState.timestampsEnabled; 701 } 702 703 Error Surface::setAutoRefreshEnabled(bool enabled) 704 { 705 ANGLE_TRY(mImplementation->setAutoRefreshEnabled(enabled)); 706 mState.autoRefreshEnabled = enabled; 707 return NoError(); 708 } 709 710 bool Surface::hasProtectedContent() const 711 { 712 return mState.hasProtectedContent(); 713 } 714 715 const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const 716 { 717 return mState.supportedCompositorTimings; 718 } 719 720 Error Surface::getCompositorTiming(EGLint numTimestamps, 721 const EGLint *names, 722 EGLnsecsANDROID *values) const 723 { 724 return mImplementation->getCompositorTiming(numTimestamps, names, values); 725 } 726 727 Error Surface::getNextFrameId(EGLuint64KHR *frameId) const 728 { 729 return mImplementation->getNextFrameId(frameId); 730 } 731 732 const SupportedTimestamps &Surface::getSupportedTimestamps() const 733 { 734 return mState.supportedTimestamps; 735 } 736 737 Error Surface::getFrameTimestamps(EGLuint64KHR frameId, 738 EGLint numTimestamps, 739 const EGLint *timestamps, 740 EGLnsecsANDROID *values) const 741 { 742 return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values); 743 } 744 745 void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) 746 { 747 ASSERT(index == kSurfaceImplSubjectIndex); 748 switch (message) 749 { 750 case angle::SubjectMessage::SubjectChanged: 751 onStateChange(angle::SubjectMessage::ContentsChanged); 752 break; 753 case angle::SubjectMessage::SurfaceChanged: 754 onStateChange(angle::SubjectMessage::SurfaceChanged); 755 break; 756 case angle::SubjectMessage::SwapchainImageChanged: 757 onStateChange(angle::SubjectMessage::SwapchainImageChanged); 758 break; 759 default: 760 UNREACHABLE(); 761 break; 762 } 763 } 764 765 Error Surface::setRenderBuffer(EGLint renderBuffer) 766 { 767 ANGLE_TRY(mImplementation->setRenderBuffer(renderBuffer)); 768 mRenderBuffer = renderBuffer; 769 return NoError(); 770 } 771 772 bool Surface::isLocked() const 773 { 774 return (mLockBufferPtr != nullptr); 775 } 776 777 EGLint Surface::getBitmapPitch() const 778 { 779 return mLockBufferPitch; 780 } 781 782 EGLint Surface::getBitmapOrigin() const 783 { 784 return mImplementation->origin(); 785 } 786 787 EGLint Surface::getRedOffset() const 788 { 789 const gl::InternalFormat &format = *mColorFormat.info; 790 if (gl::IsBGRAFormat(format.internalFormat)) 791 { 792 return format.blueBits + format.greenBits; 793 } 794 else 795 { 796 return 0; 797 } 798 } 799 800 EGLint Surface::getGreenOffset() const 801 { 802 const gl::InternalFormat &format = *mColorFormat.info; 803 if (gl::IsBGRAFormat(format.internalFormat)) 804 { 805 return format.blueBits; 806 } 807 else 808 { 809 return format.redBits; 810 } 811 } 812 813 EGLint Surface::getBlueOffset() const 814 { 815 const gl::InternalFormat &format = *mColorFormat.info; 816 if (gl::IsBGRAFormat(format.internalFormat)) 817 { 818 return 0; 819 } 820 else 821 { 822 return format.redBits + format.greenBits; 823 } 824 } 825 826 EGLint Surface::getAlphaOffset() const 827 { 828 const gl::InternalFormat &format = *mColorFormat.info; 829 if (format.isLUMA()) 830 { 831 return format.luminanceBits; // Luma always first, alpha optional 832 } 833 // For RGBA/BGRA alpha is last 834 return format.blueBits + format.greenBits + format.redBits; 835 } 836 837 EGLint Surface::getLuminanceOffset() const 838 { 839 return 0; 840 } 841 842 EGLint Surface::getBitmapPixelSize() const 843 { 844 constexpr EGLint kBitsPerByte = 8; 845 const gl::InternalFormat &format = *mColorFormat.info; 846 return (format.pixelBytes * kBitsPerByte); 847 } 848 849 EGLAttribKHR Surface::getBitmapPointer() const 850 { 851 return static_cast<EGLAttribKHR>((intptr_t)mLockBufferPtr); 852 } 853 854 egl::Error Surface::lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes) 855 { 856 EGLint lockBufferUsageHint = attributes.getAsInt( 857 EGL_LOCK_USAGE_HINT_KHR, (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR)); 858 859 bool preservePixels = ((attributes.getAsInt(EGL_MAP_PRESERVE_PIXELS_KHR, false) == EGL_TRUE) || 860 (mState.swapBehavior == EGL_BUFFER_PRESERVED)); 861 862 return mImplementation->lockSurface(display, lockBufferUsageHint, preservePixels, 863 &mLockBufferPtr, &mLockBufferPitch); 864 } 865 866 egl::Error Surface::unlockSurfaceKHR(const egl::Display *display) 867 { 868 mLockBufferPtr = nullptr; 869 mLockBufferPitch = 0; 870 return mImplementation->unlockSurface(display, true); 871 } 872 873 WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory, 874 const egl::Config *config, 875 EGLNativeWindowType window, 876 const AttributeMap &attribs, 877 bool robustResourceInit) 878 : Surface(EGL_WINDOW_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) 879 { 880 mImplementation = implFactory->createWindowSurface(mState, window, attribs); 881 } 882 883 void Surface::setDamageRegion(const EGLint *rects, EGLint n_rects) 884 { 885 mIsDamageRegionSet = true; 886 } 887 888 WindowSurface::~WindowSurface() {} 889 890 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, 891 const Config *config, 892 const AttributeMap &attribs, 893 bool robustResourceInit) 894 : Surface(EGL_PBUFFER_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) 895 { 896 mImplementation = implFactory->createPbufferSurface(mState, attribs); 897 } 898 899 PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, 900 const Config *config, 901 EGLenum buftype, 902 EGLClientBuffer clientBuffer, 903 const AttributeMap &attribs, 904 bool robustResourceInit) 905 : Surface(EGL_PBUFFER_BIT, 906 implFactory->getNextSurfaceID(), 907 config, 908 attribs, 909 robustResourceInit, 910 buftype) 911 { 912 mImplementation = 913 implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs); 914 } 915 916 PbufferSurface::~PbufferSurface() {} 917 918 PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory, 919 const Config *config, 920 NativePixmapType nativePixmap, 921 const AttributeMap &attribs, 922 bool robustResourceInit) 923 : Surface(EGL_PIXMAP_BIT, implFactory->getNextSurfaceID(), config, attribs, robustResourceInit) 924 { 925 mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs); 926 } 927 928 PixmapSurface::~PixmapSurface() {} 929 930 // SurfaceDeleter implementation. 931 932 SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {} 933 934 SurfaceDeleter::~SurfaceDeleter() {} 935 936 void SurfaceDeleter::operator()(Surface *surface) 937 { 938 ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay)); 939 } 940 941 } // namespace egl