Edit

kc3-lang/angle/src/libANGLE/Surface.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2016-07-22 22:13:26
    Hash : a3944d4f
    Message : Add gl::Format to represent a texture/rb/surface format. This has a few advantages: it preserves all the information of the internal format, such as if it is sized or unsized. It also saves looking up the format multiple times in the table, which should improve speed in some cases. The extra sized-ness information will allow us to perform the correct validation in CopyTexSubImage calls. BUG=angleproject:1228 Change-Id: I42954771b0a9a968f5d787b8cf6e0af721791855 Reviewed-on: https://chromium-review.googlesource.com/362626 Reviewed-by: Geoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/Surface.cpp
  • //
    // 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::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());
    
        texture->bindTexImageFromSurface(this);
        mTexture.set(texture);
        return mImplementation->bindTexImage(texture, buffer);
    }
    
    Error Surface::releaseTexImage(EGLint buffer)
    {
        ASSERT(mTexture.get());
        mTexture->releaseTexImageFromSurface();
        mTexture.set(nullptr);
    
        return mImplementation->releaseTexImage(buffer);
    }
    
    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,
                                   EGLClientBuffer shareHandle,
                                   const AttributeMap &attribs)
        : Surface(EGL_PBUFFER_BIT, config, attribs)
    {
        mImplementation =
            implFactory->createPbufferFromClientBuffer(mState, config, shareHandle, 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