summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/Surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/Surface.cpp')
-rwxr-xr-xgfx/angle/src/libANGLE/Surface.cpp336
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