diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/Surface.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/Surface.cpp | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/Surface.cpp b/gfx/angle/src/libANGLE/Surface.cpp new file mode 100755 index 000000000..43e71df31 --- /dev/null +++ b/gfx/angle/src/libANGLE/Surface.cpp @@ -0,0 +1,336 @@ +// +// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Surface.cpp: Implements the egl::Surface class, representing a drawing surface +// such as the client area of a window, including any back buffers. +// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. + +#include "libANGLE/Surface.h" + +#include <EGL/eglext.h> + +#include <iostream> + +#include "libANGLE/Config.h" +#include "libANGLE/Framebuffer.h" +#include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/EGLImplFactory.h" + +namespace egl +{ + +SurfaceState::SurfaceState() : defaultFramebuffer(nullptr) +{ +} + +Surface::Surface(EGLint surfaceType, const egl::Config *config, const AttributeMap &attributes) + : FramebufferAttachmentObject(), + mImplementation(nullptr), + mCurrentCount(0), + mDestroyed(false), + mType(surfaceType), + mConfig(config), + mPostSubBufferRequested(false), + mFixedSize(false), + mFixedWidth(0), + mFixedHeight(0), + mTextureFormat(EGL_NO_TEXTURE), + mTextureTarget(EGL_NO_TEXTURE), + // FIXME: Determine actual pixel aspect ratio + mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)), + mRenderBuffer(EGL_BACK_BUFFER), + mSwapBehavior(EGL_NONE), + mOrientation(0), + mTexture(), + mBackFormat(config->renderTargetFormat), + mDSFormat(config->depthStencilFormat) +{ + mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE); + mFlexibleSurfaceCompatibilityRequested = + (attributes.get(EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE, EGL_FALSE) == EGL_TRUE); + + mDirectComposition = (attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE); + + mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE); + if (mFixedSize) + { + mFixedWidth = static_cast<size_t>(attributes.get(EGL_WIDTH, 0)); + mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0)); + } + + if (mType != EGL_WINDOW_BIT) + { + mTextureFormat = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE)); + mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE)); + } + + mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0)); +} + +Surface::~Surface() +{ + if (mTexture.get()) + { + if (mImplementation) + { + mImplementation->releaseTexImage(EGL_BACK_BUFFER); + } + mTexture->releaseTexImageFromSurface(); + mTexture.set(nullptr); + } + + SafeDelete(mState.defaultFramebuffer); + SafeDelete(mImplementation); +} + +Error Surface::initialize() +{ + ANGLE_TRY(mImplementation->initialize()); + + // Initialized here since impl is nullptr in the constructor. + // Must happen after implementation initialize for Android. + mSwapBehavior = mImplementation->getSwapBehavior(); + + // Must happen after implementation initialize for OSX. + mState.defaultFramebuffer = createDefaultFramebuffer(); + ASSERT(mState.defaultFramebuffer != nullptr); + + return Error(EGL_SUCCESS); +} + +void Surface::setIsCurrent(bool isCurrent) +{ + if (isCurrent) + { + mCurrentCount++; + } + else + { + ASSERT(mCurrentCount > 0); + mCurrentCount--; + if (mCurrentCount == 0 && mDestroyed) + { + delete this; + } + } +} + +void Surface::onDestroy() +{ + mDestroyed = true; + if (mCurrentCount == 0) + { + delete this; + } +} + +EGLint Surface::getType() const +{ + return mType; +} + +Error Surface::swap() +{ + return mImplementation->swap(); +} + +Error Surface::swapWithDamage(EGLint *rects, EGLint n_rects) +{ + return mImplementation->swapWithDamage(rects, n_rects); +} + +Error Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + return mImplementation->postSubBuffer(x, y, width, height); +} + +Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + return mImplementation->querySurfacePointerANGLE(attribute, value); +} + +EGLint Surface::isPostSubBufferSupported() const +{ + return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported(); +} + +void Surface::setSwapInterval(EGLint interval) +{ + mImplementation->setSwapInterval(interval); +} + +const Config *Surface::getConfig() const +{ + return mConfig; +} + +EGLint Surface::getPixelAspectRatio() const +{ + return mPixelAspectRatio; +} + +EGLenum Surface::getRenderBuffer() const +{ + return mRenderBuffer; +} + +EGLenum Surface::getSwapBehavior() const +{ + return mSwapBehavior; +} + +EGLenum Surface::getTextureFormat() const +{ + return mTextureFormat; +} + +EGLenum Surface::getTextureTarget() const +{ + return mTextureTarget; +} + +EGLint Surface::isFixedSize() const +{ + return mFixedSize; +} + +EGLint Surface::getWidth() const +{ + return mFixedSize ? static_cast<EGLint>(mFixedWidth) : mImplementation->getWidth(); +} + +EGLint Surface::getHeight() const +{ + return mFixedSize ? static_cast<EGLint>(mFixedHeight) : mImplementation->getHeight(); +} + +Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + ASSERT(!mTexture.get()); + ANGLE_TRY(mImplementation->bindTexImage(texture, buffer)); + + texture->bindTexImageFromSurface(this); + mTexture.set(texture); + + return Error(EGL_SUCCESS); +} + +Error Surface::releaseTexImage(EGLint buffer) +{ + ANGLE_TRY(mImplementation->releaseTexImage(buffer)); + + ASSERT(mTexture.get()); + mTexture->releaseTexImageFromSurface(); + mTexture.set(nullptr); + + return Error(EGL_SUCCESS); +} + +void Surface::releaseTexImageFromTexture() +{ + ASSERT(mTexture.get()); + mTexture.set(nullptr); +} + +gl::Extents Surface::getAttachmentSize(const gl::FramebufferAttachment::Target & /*target*/) const +{ + return gl::Extents(getWidth(), getHeight(), 1); +} + +const gl::Format &Surface::getAttachmentFormat( + const gl::FramebufferAttachment::Target &target) const +{ + return (target.binding() == GL_BACK ? mBackFormat : mDSFormat); +} + +GLsizei Surface::getAttachmentSamples(const gl::FramebufferAttachment::Target &target) const +{ + return getConfig()->samples; +} + +GLuint Surface::getId() const +{ + UNREACHABLE(); + return 0; +} + +gl::Framebuffer *Surface::createDefaultFramebuffer() +{ + gl::Framebuffer *framebuffer = new gl::Framebuffer(mImplementation); + + GLenum drawBufferState = GL_BACK; + framebuffer->setDrawBuffers(1, &drawBufferState); + framebuffer->setReadBuffer(GL_BACK); + + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_BACK, gl::ImageIndex::MakeInvalid(), + this); + + if (mConfig->depthSize > 0) + { + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, gl::ImageIndex::MakeInvalid(), + this); + } + + if (mConfig->stencilSize > 0) + { + framebuffer->setAttachment(GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, + gl::ImageIndex::MakeInvalid(), this); + } + + return framebuffer; +} + +WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory, + const egl::Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs) + : Surface(EGL_WINDOW_BIT, config, attribs) +{ + mImplementation = implFactory->createWindowSurface(mState, config, window, attribs); +} + +WindowSurface::~WindowSurface() +{ +} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs) + : Surface(EGL_PBUFFER_BIT, config, attribs) +{ + mImplementation = implFactory->createPbufferSurface(mState, config, attribs); +} + +PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLenum buftype, + EGLClientBuffer clientBuffer, + const AttributeMap &attribs) + : Surface(EGL_PBUFFER_BIT, config, attribs) +{ + mImplementation = + implFactory->createPbufferFromClientBuffer(mState, config, buftype, clientBuffer, attribs); +} + +PbufferSurface::~PbufferSurface() +{ +} + +PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory, + const Config *config, + NativePixmapType nativePixmap, + const AttributeMap &attribs) + : Surface(EGL_PIXMAP_BIT, config, attribs) +{ + mImplementation = implFactory->createPixmapSurface(mState, config, nativePixmap, attribs); +} + +PixmapSurface::~PixmapSurface() +{ +} + +} // namespace egl |