Commit 1aca922a by Geoff Lang

Track more information at the egl::Surface level.

Many of the members of SurfaceImpl could be stored in egl::Surface instead. This makes SurfaceImpl a pure interface and makes Surface constructors much simpler. BUG=angleproject:795 Change-Id: Ifa797b4bef84afe66f9fb3f3a6be260f726ca55c Reviewed-on: https://chromium-review.googlesource.com/261358Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3917f578
......@@ -14,6 +14,8 @@
#include "libANGLE/Texture.h"
#include "libANGLE/renderer/SurfaceImpl.h"
#include <EGL/eglext.h>
namespace egl
{
......@@ -21,12 +23,32 @@ Surface::Surface(rx::SurfaceImpl *impl, EGLint surfaceType, const egl::Config *c
: mImplementation(impl),
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_BUFFER_PRESERVED),
mTexture(NULL)
{
mPostSubBufferRequested = (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);
mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
if (mFixedSize)
{
mFixedWidth = attributes.get(EGL_WIDTH, 0);
mFixedHeight = attributes.get(EGL_HEIGHT, 0);
}
if (mType != EGL_WINDOW_BIT)
{
mTextureFormat = attributes.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
mTextureTarget = attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
}
}
Surface::~Surface()
......@@ -66,7 +88,7 @@ Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
EGLint Surface::isPostSubBufferSupported() const
{
return mImplementation->isPostSubBufferSupported();
return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
}
void Surface::setSwapInterval(EGLint interval)
......@@ -96,32 +118,27 @@ EGLenum Surface::getSwapBehavior() const
EGLenum Surface::getTextureFormat() const
{
return mImplementation->getTextureFormat();
return mTextureFormat;
}
EGLenum Surface::getTextureTarget() const
{
return mImplementation->getTextureTarget();
return mTextureTarget;
}
EGLint Surface::isFixedSize() const
{
return mImplementation->isFixedSize();
}
EGLenum Surface::getFormat() const
{
return mImplementation->getFormat();
return mFixedSize;
}
EGLint Surface::getWidth() const
{
return mImplementation->getWidth();
return mFixedSize ? mFixedWidth : mImplementation->getWidth();
}
EGLint Surface::getHeight() const
{
return mImplementation->getHeight();
return mFixedSize ? mFixedHeight : mImplementation->getHeight();
}
Error Surface::bindTexImage(gl::Texture *texture, EGLint buffer)
......
......@@ -63,7 +63,6 @@ class Surface final : angle::NonCopyable
EGLenum getSwapBehavior() const;
EGLenum getTextureFormat() const;
EGLenum getTextureTarget() const;
EGLenum getFormat() const;
gl::Texture *getBoundTexture() const { return mTexture; }
......@@ -76,6 +75,15 @@ class Surface final : angle::NonCopyable
const egl::Config *mConfig;
bool mPostSubBufferRequested;
bool mFixedSize;
size_t mFixedWidth;
size_t mFixedHeight;
EGLenum mTextureFormat;
EGLenum mTextureTarget;
EGLint mPixelAspectRatio; // Display aspect ratio
EGLenum mRenderBuffer; // Render buffer
EGLenum mSwapBehavior; // Buffer swap behavior
......
......@@ -28,7 +28,7 @@ class MockSurfaceImpl : public rx::SurfaceImpl
MOCK_METHOD1(setSwapInterval, void(EGLint));
MOCK_CONST_METHOD0(getWidth, EGLint());
MOCK_CONST_METHOD0(getHeight, EGLint());
MOCK_CONST_METHOD0(getWindowHandle, EGLNativeWindowType());
MOCK_CONST_METHOD0(isPostSubBufferSupported, EGLint(void));
MOCK_METHOD0(destroy, void());
};
......
......@@ -8,20 +8,10 @@
#include "libANGLE/renderer/SurfaceImpl.h"
#include "libANGLE/Config.h"
namespace rx
{
SurfaceImpl::SurfaceImpl(egl::Display *display, const egl::Config *config,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType)
: mDisplay(display),
mConfig(config),
mFixedSize(fixedSize),
mPostSubBufferSupported(postSubBufferSupported),
mTextureFormat(textureFormat),
mTextureTarget(textureType)
SurfaceImpl::SurfaceImpl()
{
}
......@@ -29,9 +19,4 @@ SurfaceImpl::~SurfaceImpl()
{
}
EGLenum SurfaceImpl::getFormat() const
{
return mConfig->renderTargetFormat;
}
}
......@@ -24,9 +24,7 @@ namespace rx
class SurfaceImpl : angle::NonCopyable
{
public:
SurfaceImpl(egl::Display *display, const egl::Config *config,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType);
SurfaceImpl();
virtual ~SurfaceImpl();
virtual egl::Error initialize() = 0;
......@@ -41,39 +39,7 @@ class SurfaceImpl : angle::NonCopyable
virtual EGLint getWidth() const = 0;
virtual EGLint getHeight() const = 0;
const egl::Config *getConfig() const { return mConfig; }
EGLint isFixedSize() const { return mFixedSize; }
EGLenum getFormat() const;
EGLint isPostSubBufferSupported() const { return mPostSubBufferSupported; }
EGLenum getTextureFormat() const { return mTextureFormat; }
EGLenum getTextureTarget() const { return mTextureTarget; }
protected:
// Useful for mocking
SurfaceImpl()
: mDisplay(nullptr),
mConfig(nullptr),
mFixedSize(0),
mPostSubBufferSupported(0),
mTextureFormat(EGL_NONE),
mTextureTarget(EGL_NONE)
{}
egl::Display *const mDisplay;
const egl::Config *mConfig; // EGL config surface was created with
EGLint mFixedSize;
EGLint mPostSubBufferSupported;
// EGLint horizontalResolution; // Horizontal dot pitch
// EGLint verticalResolution; // Vertical dot pitch
// EGLBoolean largestPBuffer; // If true, create largest pbuffer possible
// EGLBoolean mipmapTexture; // True if texture has mipmaps
// EGLint mipmapLevel; // Mipmap level to render to
// EGLenum multisampleResolve; // Multisample resolve behavior
EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture
EGLenum mTextureTarget; // Type of texture: 2D or no texture
// EGLenum vgAlphaFormat; // Alpha format for OpenVG
// EGLenum vgColorSpace; // Color space for OpenVG
virtual EGLint isPostSubBufferSupported() const = 0;
};
}
......
......@@ -151,7 +151,6 @@ egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGL
{
ASSERT(mRenderer != nullptr);
EGLint postSubBufferSupported = attribs.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE);
EGLint width = attribs.get(EGL_WIDTH, 0);
EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLint fixedSize = attribs.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE);
......@@ -163,7 +162,7 @@ egl::Error DisplayD3D::createWindowSurface(const egl::Config *configuration, EGL
}
SurfaceD3D *surface = SurfaceD3D::createFromWindow(mRenderer, mDisplay, configuration, window, fixedSize,
width, height, postSubBufferSupported);
width, height);
egl::Error error = surface->initialize();
if (error.isError())
{
......@@ -182,11 +181,8 @@ egl::Error DisplayD3D::createPbufferSurface(const egl::Config *configuration, co
EGLint width = attribs.get(EGL_WIDTH, 0);
EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLenum textureFormat = attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
EGLenum textureTarget = attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, NULL,
width, height, textureFormat, textureTarget);
SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, NULL, width, height);
egl::Error error = surface->initialize();
if (error.isError())
{
......@@ -205,11 +201,9 @@ egl::Error DisplayD3D::createPbufferFromClientBuffer(const egl::Config *configur
EGLint width = attribs.get(EGL_WIDTH, 0);
EGLint height = attribs.get(EGL_HEIGHT, 0);
EGLenum textureFormat = attribs.get(EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE);
EGLenum textureTarget = attribs.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE);
SurfaceD3D *surface = SurfaceD3D::createOffscreen(mRenderer, mDisplay, configuration, shareHandle,
width, height, textureFormat, textureTarget);
width, height);
egl::Error error = surface->initialize();
if (error.isError())
{
......
......@@ -21,24 +21,25 @@ namespace rx
{
SurfaceD3D *SurfaceD3D::createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLClientBuffer shareHandle,
EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType)
EGLint width, EGLint height)
{
return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, EGL_FALSE,
textureFormat, textureType, shareHandle, NULL);
return new SurfaceD3D(renderer, display, config, width, height, EGL_TRUE, shareHandle, NULL);
}
SurfaceD3D *SurfaceD3D::createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLNativeWindowType window,
EGLint fixedSize, EGLint width, EGLint height, EGLint postSubBufferSupported)
EGLint fixedSize, EGLint width, EGLint height)
{
return new SurfaceD3D(renderer, display, config, width, height, fixedSize, postSubBufferSupported,
EGL_NO_TEXTURE, EGL_NO_TEXTURE, static_cast<EGLClientBuffer>(0), window);
return new SurfaceD3D(renderer, display, config, width, height, fixedSize, static_cast<EGLClientBuffer>(0), window);
}
SurfaceD3D::SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType, EGLClientBuffer shareHandle, EGLNativeWindowType window)
: SurfaceImpl(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType),
SurfaceD3D::SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height, EGLint fixedSize,
EGLClientBuffer shareHandle, EGLNativeWindowType window)
: SurfaceImpl(),
mRenderer(renderer),
mDisplay(display),
mFixedSize(fixedSize == EGL_TRUE),
mRenderTargetFormat(config->renderTargetFormat),
mDepthStencilFormat(config->depthStencilFormat),
mSwapChain(NULL),
mSwapIntervalDirty(true),
mWindowSubclassed(false),
......@@ -118,9 +119,7 @@ egl::Error SurfaceD3D::resetSwapChain()
height = mHeight;
}
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle,
mConfig->renderTargetFormat,
mConfig->depthStencilFormat);
mSwapChain = mRenderer->createSwapChain(mNativeWindow, mShareHandle, mRenderTargetFormat, mDepthStencilFormat);
if (!mSwapChain)
{
return egl::Error(EGL_BAD_ALLOC);
......@@ -365,9 +364,6 @@ void SurfaceD3D::setSwapInterval(EGLint interval)
}
mSwapInterval = interval;
mSwapInterval = std::max(mSwapInterval, mConfig->minSwapInterval);
mSwapInterval = std::min(mSwapInterval, mConfig->maxSwapInterval);
mSwapIntervalDirty = true;
}
......@@ -381,6 +377,12 @@ EGLint SurfaceD3D::getHeight() const
return mHeight;
}
EGLint SurfaceD3D::isPostSubBufferSupported() const
{
// post sub buffer is always possible on D3D surfaces
return EGL_TRUE;
}
egl::Error SurfaceD3D::querySurfacePointerANGLE(EGLint attribute, void **value)
{
ASSERT(attribute == EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE);
......
......@@ -26,11 +26,9 @@ class SurfaceD3D : public SurfaceImpl
{
public:
static SurfaceD3D *createFromWindow(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLNativeWindowType window, EGLint fixedSize,
EGLint width, EGLint height, EGLint postSubBufferSupported);
EGLNativeWindowType window, EGLint fixedSize, EGLint width, EGLint height);
static SurfaceD3D *createOffscreen(RendererD3D *renderer, egl::Display *display, const egl::Config *config,
EGLClientBuffer shareHandle, EGLint width, EGLint height,
EGLenum textureFormat, EGLenum textureTarget);
EGLClientBuffer shareHandle, EGLint width, EGLint height);
~SurfaceD3D() override;
void releaseSwapChain();
......@@ -46,6 +44,8 @@ class SurfaceD3D : public SurfaceImpl
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
// D3D implementations (some virtual to hack across DLL boundaries)
virtual SwapChainD3D *getSwapChain() const;
......@@ -56,8 +56,8 @@ class SurfaceD3D : public SurfaceImpl
private:
SurfaceD3D(RendererD3D *renderer, egl::Display *display, const egl::Config *config, EGLint width, EGLint height,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType, EGLClientBuffer shareHandle, EGLNativeWindowType window);
EGLint fixedSize, EGLClientBuffer shareHandle, EGLNativeWindowType window);
egl::Error swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
egl::Error resetSwapChain(int backbufferWidth, int backbufferHeight);
egl::Error resizeSwapChain(int backbufferWidth, int backbufferHeight);
......@@ -66,6 +66,12 @@ class SurfaceD3D : public SurfaceImpl
void unsubclassWindow();
RendererD3D *mRenderer;
egl::Display *mDisplay;
bool mFixedSize;
GLenum mRenderTargetFormat;
GLenum mDepthStencilFormat;
SwapChainD3D *mSwapChain;
bool mSwapIntervalDirty;
......
......@@ -11,6 +11,7 @@
#include "common/mathutil.h"
#include "common/utilities.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/Config.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Texture.h"
......@@ -894,7 +895,7 @@ gl::Error TextureD3D_2D::setStorage(GLenum target, size_t levels, GLenum interna
void TextureD3D_2D::bindTexImage(egl::Surface *surface)
{
GLenum internalformat = surface->getFormat();
GLenum internalformat = surface->getConfig()->renderTargetFormat;
gl::Extents size(surface->getWidth(), surface->getHeight(), 1);
mImageArray[0]->redefine(GL_TEXTURE_2D, internalformat, size, true);
......
......@@ -10,12 +10,12 @@
#include "common/debug.h"
#include "libANGLE/Config.h"
#include "libANGLE/renderer/gl/SurfaceGL.h"
#include "libANGLE/Surface.h"
namespace rx
{
DefaultAttachmentGL::DefaultAttachmentGL(GLenum type, SurfaceGL *surface)
DefaultAttachmentGL::DefaultAttachmentGL(GLenum type, egl::Surface *surface)
: DefaultAttachmentImpl(),
mType(type),
mSurface(surface)
......
......@@ -11,15 +11,18 @@
#include "libANGLE/renderer/DefaultAttachmentImpl.h"
namespace rx
namespace egl
{
class Surface;
}
class SurfaceGL;
namespace rx
{
class DefaultAttachmentGL : public DefaultAttachmentImpl
{
public:
DefaultAttachmentGL(GLenum type, SurfaceGL *surface);
DefaultAttachmentGL(GLenum type, egl::Surface *surface);
~DefaultAttachmentGL() override;
GLsizei getWidth() const override;
......@@ -29,7 +32,7 @@ class DefaultAttachmentGL : public DefaultAttachmentImpl
private:
GLenum mType;
SurfaceGL *mSurface;
egl::Surface *mSurface;
};
}
......
......@@ -110,7 +110,7 @@ ProgramImpl *RendererGL::createProgram()
DefaultAttachmentImpl *RendererGL::createDefaultAttachment(GLenum type, egl::Surface *surface)
{
return new DefaultAttachmentGL(type, GetImplAs<SurfaceGL>(surface));
return new DefaultAttachmentGL(type, surface);
}
FramebufferImpl *RendererGL::createDefaultFramebuffer(const gl::Framebuffer::Data &data)
......
......@@ -11,10 +11,8 @@
namespace rx
{
SurfaceGL::SurfaceGL(egl::Display *display, const egl::Config *config,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType)
: SurfaceImpl(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType)
SurfaceGL::SurfaceGL()
: SurfaceImpl()
{
}
......
......@@ -17,9 +17,7 @@ namespace rx
class SurfaceGL : public SurfaceImpl
{
public:
SurfaceGL(egl::Display *display, const egl::Config *config,
EGLint fixedSize, EGLint postSubBufferSupported, EGLenum textureFormat,
EGLenum textureType);
SurfaceGL();
~SurfaceGL() override;
};
......
......@@ -337,8 +337,7 @@ void DisplayWGL::terminate()
egl::Error DisplayWGL::createWindowSurface(const egl::Config *configuration, EGLNativeWindowType window,
const egl::AttributeMap &attribs, SurfaceImpl **outSurface)
{
SurfaceWGL *surface = new SurfaceWGL(mDisplay, configuration, EGL_FALSE, EGL_FALSE, EGL_NO_TEXTURE, EGL_NO_TEXTURE,
window, mWindowClass, mPixelFormat, mWGLContext, mFunctionsWGL);
SurfaceWGL *surface = new SurfaceWGL(window, mWindowClass, mPixelFormat, mWGLContext, mFunctionsWGL);
egl::Error error = surface->initialize();
if (error.isError())
{
......
......@@ -15,10 +15,8 @@
namespace rx
{
SurfaceWGL::SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported,
EGLenum textureFormat, EGLenum textureType, EGLNativeWindowType window, ATOM windowClass, int pixelFormat,
HGLRC wglContext, const FunctionsWGL *functions)
: SurfaceGL(display, config, fixedSize, postSubBufferSupported, textureFormat, textureType),
SurfaceWGL::SurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions)
: SurfaceGL(),
mWindowClass(windowClass),
mPixelFormat(pixelFormat),
mShareWGLContext(wglContext),
......@@ -179,4 +177,11 @@ EGLint SurfaceWGL::getHeight() const
return rect.bottom - rect.top;
}
EGLint SurfaceWGL::isPostSubBufferSupported() const
{
// PostSubBuffer extension not exposed on WGL.
UNIMPLEMENTED();
return EGL_FALSE;
}
}
......@@ -21,10 +21,7 @@ class FunctionsWGL;
class SurfaceWGL : public SurfaceGL
{
public:
SurfaceWGL(egl::Display *display, const egl::Config *config, EGLint fixedSize, EGLint postSubBufferSupported,
EGLenum textureFormat, EGLenum textureType, EGLNativeWindowType window, ATOM windowClass, int pixelFormat,
HGLRC wglContext, const FunctionsWGL *functions);
SurfaceWGL(EGLNativeWindowType window, ATOM windowClass, int pixelFormat, HGLRC wglContext, const FunctionsWGL *functions);
~SurfaceWGL() override;
static SurfaceWGL *makeSurfaceWGL(SurfaceImpl *impl);
......@@ -42,6 +39,8 @@ class SurfaceWGL : public SurfaceGL
EGLint getWidth() const override;
EGLint getHeight() const override;
EGLint isPostSubBufferSupported() const override;
private:
ATOM mWindowClass;
int mPixelFormat;
......
......@@ -873,7 +873,10 @@ EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
return EGL_FALSE;
}
draw_surface->setSwapInterval(interval);
const egl::Config *surfaceConfig = draw_surface->getConfig();
EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval);
draw_surface->setSwapInterval(clampedInterval);
SetGlobalError(Error(EGL_SUCCESS));
return EGL_TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment