зеркало из https://github.com/AvaloniaUI/angle.git
Create a default framebuffer per surface/context pair on MakeCurrent.
Sharing a gl::Framebuffer object between multiple contexts causes problems if contexts are not virtualized because the native framebuffer objects are not shared between these contexts. The FramebufferImpl created should be the glue that binds a specific context to a specific surface. Update the SurfaceImpl implementations to re-create the framebuffer object before passing it to FramebufferGL. No backing resources will be re-created. BUG=angleproject:2464 Change-Id: Id0b13a221c22b71517b25cb5b1ef2392ad2ecdd6 Reviewed-on: https://chromium-review.googlesource.com/1039985 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: Frank Henigman <fjhenigman@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
cbab27508e
Коммит
bf7b95db6b
|
@ -291,7 +291,6 @@ Context::Context(rx::EGLImplFactory *implFactory,
|
|||
mRobustAccess(GetRobustAccess(attribs)),
|
||||
mCurrentSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
|
||||
mCurrentDisplay(static_cast<egl::Display *>(EGL_NO_DISPLAY)),
|
||||
mSurfacelessFramebuffer(nullptr),
|
||||
mWebGLContext(GetWebGLContext(attribs)),
|
||||
mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
|
||||
mMemoryProgramCache(memoryProgramCache),
|
||||
|
@ -445,12 +444,6 @@ egl::Error Context::onDestroy(const egl::Display *display)
|
|||
}
|
||||
|
||||
// Delete the Surface first to trigger a finish() in Vulkan.
|
||||
if (mSurfacelessFramebuffer)
|
||||
{
|
||||
mSurfacelessFramebuffer->onDestroy(this);
|
||||
SafeDelete(mSurfacelessFramebuffer);
|
||||
}
|
||||
|
||||
ANGLE_TRY(releaseSurface(display));
|
||||
|
||||
for (auto fence : mFenceNVMap)
|
||||
|
@ -553,16 +546,11 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
|
|||
{
|
||||
ANGLE_TRY(surface->setIsCurrent(this, true));
|
||||
mCurrentSurface = surface;
|
||||
newDefault = surface->getDefaultFramebuffer();
|
||||
newDefault = surface->createDefaultFramebuffer(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mSurfacelessFramebuffer == nullptr)
|
||||
{
|
||||
mSurfacelessFramebuffer = new Framebuffer(mImplementation.get());
|
||||
}
|
||||
|
||||
newDefault = mSurfacelessFramebuffer;
|
||||
newDefault = new Framebuffer(mImplementation.get());
|
||||
}
|
||||
|
||||
// Update default framebuffer, the binding of the previous default
|
||||
|
@ -586,25 +574,25 @@ egl::Error Context::makeCurrent(egl::Display *display, egl::Surface *surface)
|
|||
|
||||
egl::Error Context::releaseSurface(const egl::Display *display)
|
||||
{
|
||||
// Remove the default framebuffer
|
||||
Framebuffer *currentDefault = nullptr;
|
||||
if (mCurrentSurface != nullptr)
|
||||
{
|
||||
currentDefault = mCurrentSurface->getDefaultFramebuffer();
|
||||
}
|
||||
else if (mSurfacelessFramebuffer != nullptr)
|
||||
{
|
||||
currentDefault = mSurfacelessFramebuffer;
|
||||
}
|
||||
gl::Framebuffer *defaultFramebuffer = mState.mFramebuffers->getFramebuffer(0);
|
||||
|
||||
if (mGLState.getReadFramebuffer() == currentDefault)
|
||||
// Remove the default framebuffer
|
||||
if (mGLState.getReadFramebuffer() == defaultFramebuffer)
|
||||
{
|
||||
mGLState.setReadFramebufferBinding(nullptr);
|
||||
}
|
||||
if (mGLState.getDrawFramebuffer() == currentDefault)
|
||||
|
||||
if (mGLState.getDrawFramebuffer() == defaultFramebuffer)
|
||||
{
|
||||
mGLState.setDrawFramebufferBinding(nullptr);
|
||||
}
|
||||
|
||||
if (defaultFramebuffer)
|
||||
{
|
||||
defaultFramebuffer->onDestroy(this);
|
||||
delete defaultFramebuffer;
|
||||
}
|
||||
|
||||
mState.mFramebuffers->setDefaultFramebuffer(nullptr);
|
||||
|
||||
if (mCurrentSurface)
|
||||
|
|
|
@ -1577,7 +1577,6 @@ class Context final : angle::NonCopyable
|
|||
bool mRobustAccess;
|
||||
egl::Surface *mCurrentSurface;
|
||||
egl::Display *mCurrentDisplay;
|
||||
Framebuffer *mSurfacelessFramebuffer;
|
||||
bool mWebGLContext;
|
||||
bool mExtensionsEnabled;
|
||||
MemoryProgramCache *mMemoryProgramCache;
|
||||
|
|
|
@ -632,9 +632,9 @@ Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id
|
|||
}
|
||||
}
|
||||
|
||||
Framebuffer::Framebuffer(const egl::Display *display, egl::Surface *surface)
|
||||
Framebuffer::Framebuffer(const Context *context, egl::Surface *surface)
|
||||
: mState(),
|
||||
mImpl(surface->getImplementation()->createDefaultFramebuffer(mState)),
|
||||
mImpl(surface->getImplementation()->createDefaultFramebuffer(context, mState)),
|
||||
mCachedStatus(GL_FRAMEBUFFER_COMPLETE),
|
||||
mDirtyDepthAttachmentBinding(this, DIRTY_BIT_DEPTH_ATTACHMENT),
|
||||
mDirtyStencilAttachmentBinding(this, DIRTY_BIT_STENCIL_ATTACHMENT)
|
||||
|
@ -642,9 +642,7 @@ Framebuffer::Framebuffer(const egl::Display *display, egl::Surface *surface)
|
|||
ASSERT(mImpl != nullptr);
|
||||
mDirtyColorAttachmentBindings.emplace_back(this, DIRTY_BIT_COLOR_ATTACHMENT_0);
|
||||
|
||||
const Context *proxyContext = display->getProxyContext();
|
||||
|
||||
setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), surface,
|
||||
setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_BACK, ImageIndex(), surface,
|
||||
FramebufferAttachment::kDefaultNumViews,
|
||||
FramebufferAttachment::kDefaultBaseViewIndex,
|
||||
FramebufferAttachment::kDefaultMultiviewLayout,
|
||||
|
@ -652,7 +650,7 @@ Framebuffer::Framebuffer(const egl::Display *display, egl::Surface *surface)
|
|||
|
||||
if (surface->getConfig()->depthSize > 0)
|
||||
{
|
||||
setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex(), surface,
|
||||
setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_DEPTH, ImageIndex(), surface,
|
||||
FramebufferAttachment::kDefaultNumViews,
|
||||
FramebufferAttachment::kDefaultBaseViewIndex,
|
||||
FramebufferAttachment::kDefaultMultiviewLayout,
|
||||
|
@ -661,7 +659,7 @@ Framebuffer::Framebuffer(const egl::Display *display, egl::Surface *surface)
|
|||
|
||||
if (surface->getConfig()->stencilSize > 0)
|
||||
{
|
||||
setAttachmentImpl(proxyContext, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex(), surface,
|
||||
setAttachmentImpl(context, GL_FRAMEBUFFER_DEFAULT, GL_STENCIL, ImageIndex(), surface,
|
||||
FramebufferAttachment::kDefaultNumViews,
|
||||
FramebufferAttachment::kDefaultBaseViewIndex,
|
||||
FramebufferAttachment::kDefaultMultiviewLayout,
|
||||
|
|
|
@ -142,8 +142,8 @@ class Framebuffer final : public angle::ObserverInterface, public LabeledObject
|
|||
public:
|
||||
// Constructor to build application-defined framebuffers
|
||||
Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id);
|
||||
// Constructor to build default framebuffers for a surface
|
||||
Framebuffer(const egl::Display *display, egl::Surface *surface);
|
||||
// Constructor to build default framebuffers for a surface and context pair
|
||||
Framebuffer(const Context *context, egl::Surface *surface);
|
||||
// Constructor to build a fake default framebuffer when surfaceless
|
||||
Framebuffer(rx::GLImplFactory *factory);
|
||||
|
||||
|
|
|
@ -424,12 +424,8 @@ Framebuffer *FramebufferManager::AllocateNewObject(rx::GLImplFactory *factory,
|
|||
// static
|
||||
void FramebufferManager::DeleteObject(const Context *context, Framebuffer *framebuffer)
|
||||
{
|
||||
// Default framebuffer are owned by their respective Surface
|
||||
if (framebuffer->id() != 0)
|
||||
{
|
||||
framebuffer->onDestroy(context);
|
||||
delete framebuffer;
|
||||
}
|
||||
framebuffer->onDestroy(context);
|
||||
delete framebuffer;
|
||||
}
|
||||
|
||||
GLuint FramebufferManager::createFramebuffer()
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace egl
|
|||
{
|
||||
|
||||
SurfaceState::SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn)
|
||||
: defaultFramebuffer(nullptr), config(configIn), attributes(attributesIn)
|
||||
: config(configIn), attributes(attributesIn)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,6 @@ rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
|
|||
|
||||
Error Surface::destroyImpl(const Display *display)
|
||||
{
|
||||
if (mState.defaultFramebuffer)
|
||||
{
|
||||
mState.defaultFramebuffer->onDestroy(display->getProxyContext());
|
||||
}
|
||||
if (mImplementation)
|
||||
{
|
||||
mImplementation->destroy(display);
|
||||
|
@ -128,24 +124,19 @@ Error Surface::destroyImpl(const Display *display)
|
|||
|
||||
if (mTexture.get())
|
||||
{
|
||||
gl::Context *context = display->getProxyContext();
|
||||
if (mImplementation)
|
||||
{
|
||||
ANGLE_TRY(
|
||||
mImplementation->releaseTexImage(display->getProxyContext(), EGL_BACK_BUFFER));
|
||||
ANGLE_TRY(mImplementation->releaseTexImage(context, EGL_BACK_BUFFER));
|
||||
}
|
||||
auto glErr = mTexture->releaseTexImageFromSurface(display->getProxyContext());
|
||||
auto glErr = mTexture->releaseTexImageFromSurface(context);
|
||||
if (glErr.isError())
|
||||
{
|
||||
return Error(EGL_BAD_SURFACE);
|
||||
}
|
||||
mTexture.set(display->getProxyContext(), nullptr);
|
||||
mTexture.set(context, nullptr);
|
||||
}
|
||||
|
||||
if (mState.defaultFramebuffer)
|
||||
{
|
||||
mState.defaultFramebuffer->onDestroy(display->getProxyContext());
|
||||
}
|
||||
SafeDelete(mState.defaultFramebuffer);
|
||||
SafeDelete(mImplementation);
|
||||
|
||||
delete this;
|
||||
|
@ -169,10 +160,6 @@ Error Surface::initialize(const Display *display)
|
|||
// Must happen after implementation initialize for Android.
|
||||
mSwapBehavior = mImplementation->getSwapBehavior();
|
||||
|
||||
// Must happen after implementation initialize for OSX.
|
||||
mState.defaultFramebuffer = createDefaultFramebuffer(display);
|
||||
ASSERT(mState.defaultFramebuffer != nullptr);
|
||||
|
||||
if (mBuftype == EGL_IOSURFACE_ANGLE)
|
||||
{
|
||||
GLenum internalFormat =
|
||||
|
@ -452,9 +439,9 @@ GLuint Surface::getId() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
gl::Framebuffer *Surface::createDefaultFramebuffer(const Display *display)
|
||||
gl::Framebuffer *Surface::createDefaultFramebuffer(const gl::Context *context)
|
||||
{
|
||||
return new gl::Framebuffer(display, this);
|
||||
return new gl::Framebuffer(context, this);
|
||||
}
|
||||
|
||||
gl::InitState Surface::initState(const gl::ImageIndex & /*imageIndex*/) const
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
namespace gl
|
||||
{
|
||||
class Context;
|
||||
class Framebuffer;
|
||||
class Texture;
|
||||
}
|
||||
|
@ -42,7 +43,6 @@ struct SurfaceState final : private angle::NonCopyable
|
|||
{
|
||||
SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn);
|
||||
|
||||
gl::Framebuffer *defaultFramebuffer;
|
||||
const egl::Config *config;
|
||||
AttributeMap attributes;
|
||||
};
|
||||
|
@ -79,6 +79,8 @@ class Surface : public gl::FramebufferAttachmentObject
|
|||
void setMultisampleResolve(EGLenum resolve);
|
||||
void setSwapBehavior(EGLenum behavior);
|
||||
|
||||
gl::Framebuffer *createDefaultFramebuffer(const gl::Context *context);
|
||||
|
||||
const Config *getConfig() const;
|
||||
|
||||
// width and height can change with client window resizing
|
||||
|
@ -100,7 +102,6 @@ class Surface : public gl::FramebufferAttachmentObject
|
|||
EGLenum getMultisampleResolve() const;
|
||||
|
||||
gl::Texture *getBoundTexture() const { return mTexture.get(); }
|
||||
gl::Framebuffer *getDefaultFramebuffer() { return mState.defaultFramebuffer; }
|
||||
|
||||
EGLint isFixedSize() const;
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ class MockSurfaceImpl : public rx::SurfaceImpl
|
|||
|
||||
MOCK_METHOD1(destroy, void(const egl::Display *));
|
||||
MOCK_METHOD1(initialize, egl::Error(const egl::Display *));
|
||||
MOCK_METHOD1(createDefaultFramebuffer, rx::FramebufferImpl *(const gl::FramebufferState &data));
|
||||
MOCK_METHOD2(createDefaultFramebuffer,
|
||||
rx::FramebufferImpl *(const gl::Context *, const gl::FramebufferState &data));
|
||||
MOCK_METHOD1(swap, egl::Error(const gl::Context *));
|
||||
MOCK_METHOD3(swapWithDamage, egl::Error(const gl::Context *, EGLint *, EGLint));
|
||||
MOCK_METHOD5(postSubBuffer, egl::Error(const gl::Context *, EGLint, EGLint, EGLint, EGLint));
|
||||
|
|
|
@ -24,6 +24,7 @@ struct Format;
|
|||
|
||||
namespace gl
|
||||
{
|
||||
class Context;
|
||||
class FramebufferState;
|
||||
}
|
||||
|
||||
|
@ -47,7 +48,8 @@ class SurfaceImpl : public FramebufferAttachmentObjectImpl
|
|||
virtual void destroy(const egl::Display *display) {}
|
||||
|
||||
virtual egl::Error initialize(const egl::Display *display) = 0;
|
||||
virtual FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) = 0;
|
||||
virtual FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) = 0;
|
||||
virtual egl::Error swap(const gl::Context *context) = 0;
|
||||
virtual egl::Error swapWithDamage(const gl::Context *context, EGLint *rects, EGLint n_rects);
|
||||
virtual egl::Error postSubBuffer(const gl::Context *context,
|
||||
|
|
|
@ -132,7 +132,8 @@ egl::Error SurfaceD3D::initialize(const egl::Display *display)
|
|||
return egl::NoError();
|
||||
}
|
||||
|
||||
FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::FramebufferState &data)
|
||||
FramebufferImpl *SurfaceD3D::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data)
|
||||
{
|
||||
return mRenderer->createDefaultFramebuffer(data);
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ class SurfaceD3D : public SurfaceImpl
|
|||
void releaseSwapChain();
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
|
||||
egl::Error swap(const gl::Context *context) override;
|
||||
egl::Error postSubBuffer(const gl::Context *context,
|
||||
|
|
|
@ -26,7 +26,8 @@ SurfaceGL::~SurfaceGL()
|
|||
{
|
||||
}
|
||||
|
||||
FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::FramebufferState &data)
|
||||
FramebufferImpl *SurfaceGL::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data)
|
||||
{
|
||||
return new FramebufferGL(data, 0, true);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,8 @@ class SurfaceGL : public SurfaceImpl
|
|||
SurfaceGL(const egl::SurfaceState &state);
|
||||
~SurfaceGL() override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data) override;
|
||||
egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
|
||||
|
||||
gl::Error initializeContents(const gl::Context *context,
|
||||
|
|
|
@ -52,7 +52,8 @@ class PbufferSurfaceCGL : public SurfaceGL
|
|||
EGLint isPostSubBufferSupported() const override;
|
||||
EGLint getSwapBehavior() const override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
|
||||
private:
|
||||
unsigned mWidth;
|
||||
|
@ -63,7 +64,6 @@ class PbufferSurfaceCGL : public SurfaceGL
|
|||
const FunctionsGL *mFunctions;
|
||||
StateManagerGL *mStateManager;
|
||||
|
||||
GLuint mFramebuffer;
|
||||
GLuint mColorRenderbuffer;
|
||||
GLuint mDSRenderbuffer;
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@ PbufferSurfaceCGL::PbufferSurfaceCGL(const egl::SurfaceState &state,
|
|||
mHeight(height),
|
||||
mFunctions(functions),
|
||||
mStateManager(renderer->getStateManager()),
|
||||
mFramebuffer(0),
|
||||
mColorRenderbuffer(0),
|
||||
mDSRenderbuffer(0)
|
||||
{
|
||||
|
@ -36,12 +35,6 @@ PbufferSurfaceCGL::PbufferSurfaceCGL(const egl::SurfaceState &state,
|
|||
|
||||
PbufferSurfaceCGL::~PbufferSurfaceCGL()
|
||||
{
|
||||
if (mFramebuffer != 0)
|
||||
{
|
||||
mFunctions->deleteFramebuffers(1, &mFramebuffer);
|
||||
mFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (mColorRenderbuffer != 0)
|
||||
{
|
||||
mFunctions->deleteRenderbuffers(1, &mColorRenderbuffer);
|
||||
|
@ -64,13 +57,6 @@ egl::Error PbufferSurfaceCGL::initialize(const egl::Display *display)
|
|||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
|
||||
mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight);
|
||||
|
||||
mFunctions->genFramebuffers(1, &mFramebuffer);
|
||||
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbuffer);
|
||||
mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, mDSRenderbuffer);
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
|
@ -138,10 +124,21 @@ EGLint PbufferSurfaceCGL::getSwapBehavior() const
|
|||
return EGL_BUFFER_PRESERVED;
|
||||
}
|
||||
|
||||
FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *PbufferSurfaceCGL::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
// TODO(cwallez) assert it happens only once?
|
||||
return new FramebufferGL(state, mFramebuffer, true);
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
GLuint framebuffer = 0;
|
||||
functions->genFramebuffers(1, &framebuffer);
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbuffer);
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSRenderbuffer);
|
||||
|
||||
return new FramebufferGL(state, framebuffer, true);
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -84,7 +84,8 @@ class WindowSurfaceCGL : public SurfaceGL
|
|||
EGLint isPostSubBufferSupported() const override;
|
||||
EGLint getSwapBehavior() const override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
|
||||
private:
|
||||
SwapLayer *mSwapLayer;
|
||||
|
@ -96,7 +97,6 @@ class WindowSurfaceCGL : public SurfaceGL
|
|||
const FunctionsGL *mFunctions;
|
||||
StateManagerGL *mStateManager;
|
||||
|
||||
GLuint mFramebuffer;
|
||||
GLuint mDSRenderbuffer;
|
||||
};
|
||||
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
|
||||
#include "libANGLE/Context.h"
|
||||
#include "libANGLE/renderer/gl/FramebufferGL.h"
|
||||
#include "libANGLE/renderer/gl/RendererGL.h"
|
||||
#include "libANGLE/renderer/gl/StateManagerGL.h"
|
||||
#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
|
||||
|
||||
@interface SwapLayer : CAOpenGLLayer
|
||||
{
|
||||
|
@ -154,7 +155,6 @@
|
|||
mContext(context),
|
||||
mFunctions(functions),
|
||||
mStateManager(renderer->getStateManager()),
|
||||
mFramebuffer(0),
|
||||
mDSRenderbuffer(0)
|
||||
{
|
||||
pthread_mutex_init(&mSwapState.mutex, nullptr);
|
||||
|
@ -163,11 +163,6 @@
|
|||
WindowSurfaceCGL::~WindowSurfaceCGL()
|
||||
{
|
||||
pthread_mutex_destroy(&mSwapState.mutex);
|
||||
if (mFramebuffer != 0)
|
||||
{
|
||||
mFunctions->deleteFramebuffers(1, &mFramebuffer);
|
||||
mFramebuffer = 0;
|
||||
}
|
||||
|
||||
if (mDSRenderbuffer != 0)
|
||||
{
|
||||
|
@ -220,13 +215,6 @@ egl::Error WindowSurfaceCGL::initialize(const egl::Display *display)
|
|||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
|
||||
mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
mFunctions->genFramebuffers(1, &mFramebuffer);
|
||||
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
mSwapState.beingRendered->texture, 0);
|
||||
mFunctions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSRenderbuffer);
|
||||
|
||||
return egl::Error(EGL_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -237,7 +225,10 @@ egl::Error WindowSurfaceCGL::makeCurrent()
|
|||
|
||||
egl::Error WindowSurfaceCGL::swap(const gl::Context *context)
|
||||
{
|
||||
mFunctions->flush();
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
functions->flush();
|
||||
mSwapState.beingRendered->swapId = ++mCurrentSwapId;
|
||||
|
||||
pthread_mutex_lock(&mSwapState.mutex);
|
||||
|
@ -252,20 +243,21 @@ egl::Error WindowSurfaceCGL::swap(const gl::Context *context)
|
|||
|
||||
if (texture.width != width || texture.height != height)
|
||||
{
|
||||
mStateManager->bindTexture(gl::TextureType::_2D, texture.texture);
|
||||
mFunctions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
stateManager->bindTexture(gl::TextureType::_2D, texture.texture);
|
||||
functions->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
|
||||
mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
stateManager->bindRenderbuffer(GL_RENDERBUFFER, mDSRenderbuffer);
|
||||
functions->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
|
||||
texture.width = width;
|
||||
texture.height = height;
|
||||
}
|
||||
|
||||
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
mSwapState.beingRendered->texture, 0);
|
||||
FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(context->getFramebuffer(0));
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebufferGL->getFramebufferID());
|
||||
functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
mSwapState.beingRendered->texture, 0);
|
||||
|
||||
return egl::Error(EGL_SUCCESS);
|
||||
}
|
||||
|
@ -326,10 +318,21 @@ EGLint WindowSurfaceCGL::getSwapBehavior() const
|
|||
return EGL_BUFFER_DESTROYED;
|
||||
}
|
||||
|
||||
FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *WindowSurfaceCGL::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
// TODO(cwallez) assert it happens only once?
|
||||
return new FramebufferGL(state, mFramebuffer, true);
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
GLuint framebuffer = 0;
|
||||
functions->genFramebuffers(1, &framebuffer);
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
mSwapState.beingRendered->texture, 0);
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSRenderbuffer);
|
||||
|
||||
return new FramebufferGL(state, framebuffer, true);
|
||||
}
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -113,15 +113,19 @@ DisplayOzone::Buffer::Buffer(DisplayOzone *display,
|
|||
mImage(EGL_NO_IMAGE_KHR),
|
||||
mColorBuffer(0),
|
||||
mDSBuffer(0),
|
||||
mGLFB(0),
|
||||
mTexture(0)
|
||||
{
|
||||
}
|
||||
|
||||
DisplayOzone::Buffer::~Buffer()
|
||||
{
|
||||
mDisplay->mFunctionsGL->deleteFramebuffers(1, &mGLFB);
|
||||
reset();
|
||||
|
||||
FunctionsGL *gl = mDisplay->mFunctionsGL;
|
||||
gl->deleteRenderbuffers(1, &mColorBuffer);
|
||||
mColorBuffer = 0;
|
||||
gl->deleteRenderbuffers(1, &mDSBuffer);
|
||||
mDSBuffer = 0;
|
||||
}
|
||||
|
||||
void DisplayOzone::Buffer::reset()
|
||||
|
@ -133,15 +137,8 @@ void DisplayOzone::Buffer::reset()
|
|||
mHasDRMFB = false;
|
||||
}
|
||||
|
||||
FunctionsGL *gl = mDisplay->mFunctionsGL;
|
||||
gl->deleteRenderbuffers(1, &mColorBuffer);
|
||||
mColorBuffer = 0;
|
||||
gl->deleteRenderbuffers(1, &mDSBuffer);
|
||||
mDSBuffer = 0;
|
||||
|
||||
// Here we might destroy the GL framebuffer (mGLFB) but unlike every other resource in Buffer,
|
||||
// it does not get destroyed (and recreated) because when it is the default framebuffer for
|
||||
// an ANGLE surface then ANGLE expects it to have the same lifetime as that surface.
|
||||
// Make sure to keep the color and depth stencil buffers alive so they maintain the same GL IDs
|
||||
// if they are bound to any emulated default framebuffer.
|
||||
|
||||
if (mImage != EGL_NO_IMAGE_KHR)
|
||||
{
|
||||
|
@ -151,6 +148,7 @@ void DisplayOzone::Buffer::reset()
|
|||
|
||||
if (mTexture)
|
||||
{
|
||||
FunctionsGL *gl = mDisplay->mFunctionsGL;
|
||||
gl->deleteTextures(1, &mTexture);
|
||||
mTexture = 0;
|
||||
}
|
||||
|
@ -216,33 +214,17 @@ bool DisplayOzone::Buffer::resize(int32_t width, int32_t height)
|
|||
FunctionsGL *gl = mDisplay->mFunctionsGL;
|
||||
StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
|
||||
|
||||
gl->genRenderbuffers(1, &mColorBuffer);
|
||||
// Update the storage of the renderbuffers but don't generate new IDs. This will update all
|
||||
// framebuffers they are bound to.
|
||||
sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer);
|
||||
gl->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
|
||||
|
||||
sm->bindFramebuffer(GL_FRAMEBUFFER, mGLFB);
|
||||
gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER,
|
||||
mColorBuffer);
|
||||
|
||||
if (mDepthBits || mStencilBits)
|
||||
{
|
||||
gl->genRenderbuffers(1, &mDSBuffer);
|
||||
sm->bindRenderbuffer(GL_RENDERBUFFER, mDSBuffer);
|
||||
gl->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
|
||||
}
|
||||
|
||||
if (mDepthBits)
|
||||
{
|
||||
gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSBuffer);
|
||||
}
|
||||
|
||||
if (mStencilBits)
|
||||
{
|
||||
gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSBuffer);
|
||||
}
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
return true;
|
||||
|
@ -251,14 +233,12 @@ bool DisplayOzone::Buffer::resize(int32_t width, int32_t height)
|
|||
bool DisplayOzone::Buffer::initialize(const NativeWindow *native)
|
||||
{
|
||||
mNative = native;
|
||||
mDisplay->mFunctionsGL->genFramebuffers(1, &mGLFB);
|
||||
return resize(native->width, native->height);
|
||||
return createRenderbuffers() && resize(native->width, native->height);
|
||||
}
|
||||
|
||||
bool DisplayOzone::Buffer::initialize(int width, int height)
|
||||
{
|
||||
mDisplay->mFunctionsGL->genFramebuffers(1, &mGLFB);
|
||||
return resize(width, height);
|
||||
return createRenderbuffers() && resize(width, height);
|
||||
}
|
||||
|
||||
void DisplayOzone::Buffer::bindTexImage()
|
||||
|
@ -305,29 +285,70 @@ uint32_t DisplayOzone::Buffer::getDRMFB()
|
|||
return mDRMFB;
|
||||
}
|
||||
|
||||
FramebufferGL *DisplayOzone::Buffer::framebufferGL(const gl::FramebufferState &state)
|
||||
GLuint DisplayOzone::Buffer::createGLFB(const gl::Context *context)
|
||||
{
|
||||
return new FramebufferGL(state, mGLFB, true);
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
GLuint framebuffer = 0;
|
||||
functions->genFramebuffers(1, &framebuffer);
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER,
|
||||
mColorBuffer);
|
||||
|
||||
if (mDepthBits)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSBuffer);
|
||||
}
|
||||
|
||||
if (mStencilBits)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDSBuffer);
|
||||
}
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
void DisplayOzone::Buffer::present()
|
||||
FramebufferGL *DisplayOzone::Buffer::framebufferGL(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
return new FramebufferGL(state, createGLFB(context), true);
|
||||
}
|
||||
|
||||
void DisplayOzone::Buffer::present(const gl::Context *context)
|
||||
{
|
||||
if (mNative)
|
||||
{
|
||||
if (mNative->visible)
|
||||
{
|
||||
mDisplay->drawBuffer(this);
|
||||
mDisplay->drawBuffer(context, this);
|
||||
}
|
||||
resize(mNative->width, mNative->height);
|
||||
}
|
||||
}
|
||||
|
||||
bool DisplayOzone::Buffer::createRenderbuffers()
|
||||
{
|
||||
FunctionsGL *gl = mDisplay->mFunctionsGL;
|
||||
StateManagerGL *sm = mDisplay->getRenderer()->getStateManager();
|
||||
|
||||
gl->genRenderbuffers(1, &mColorBuffer);
|
||||
sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer);
|
||||
|
||||
if (mDepthBits || mStencilBits)
|
||||
{
|
||||
gl->genRenderbuffers(1, &mDSBuffer);
|
||||
sm->bindRenderbuffer(GL_RENDERBUFFER, mDSBuffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
DisplayOzone::DisplayOzone(const egl::DisplayState &state)
|
||||
: DisplayEGL(state),
|
||||
mSwapControl(SwapControl::ABSENT),
|
||||
mMinSwapInterval(0),
|
||||
mMaxSwapInterval(0),
|
||||
mCurrentSwapInterval(-1),
|
||||
mGBM(nullptr),
|
||||
mConnector(nullptr),
|
||||
mMode(nullptr),
|
||||
|
@ -603,7 +624,7 @@ GLuint DisplayOzone::makeShader(GLuint type, const char *src)
|
|||
return shader;
|
||||
}
|
||||
|
||||
void DisplayOzone::drawWithTexture(Buffer *buffer)
|
||||
void DisplayOzone::drawWithTexture(const gl::Context *context, Buffer *buffer)
|
||||
{
|
||||
FunctionsGL *gl = mFunctionsGL;
|
||||
StateManagerGL *sm = getRenderer()->getStateManager();
|
||||
|
@ -727,13 +748,15 @@ void DisplayOzone::drawWithTexture(Buffer *buffer)
|
|||
sm->bindTexture(gl::TextureType::_2D, tex);
|
||||
gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
|
||||
gl->enableVertexAttribArray(0);
|
||||
sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB());
|
||||
GLuint fbo = mDrawing->createGLFB(context);
|
||||
sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
gl->drawElements(GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_INT, 0);
|
||||
sm->deleteTexture(tex);
|
||||
sm->deleteFramebuffer(fbo);
|
||||
}
|
||||
|
||||
void DisplayOzone::drawBuffer(Buffer *buffer)
|
||||
void DisplayOzone::drawBuffer(const gl::Context *context, Buffer *buffer)
|
||||
{
|
||||
if (!mDrawing)
|
||||
{
|
||||
|
@ -755,16 +778,19 @@ void DisplayOzone::drawBuffer(Buffer *buffer)
|
|||
}
|
||||
|
||||
StateManagerGL *sm = getRenderer()->getStateManager();
|
||||
sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB());
|
||||
|
||||
GLuint fbo = mDrawing->createGLFB(context);
|
||||
sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
sm->setClearColor(gl::ColorF(0, 0, 0, 1));
|
||||
sm->setClearDepth(1);
|
||||
sm->setScissorTestEnabled(false);
|
||||
sm->setColorMask(true, true, true, true);
|
||||
sm->setDepthMask(true);
|
||||
mFunctionsGL->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
sm->deleteFramebuffer(fbo);
|
||||
}
|
||||
|
||||
drawWithTexture(buffer);
|
||||
drawWithTexture(context, buffer);
|
||||
presentScreen();
|
||||
}
|
||||
|
||||
|
|
|
@ -75,17 +75,19 @@ class DisplayOzone final : public DisplayEGL
|
|||
bool initialize(int32_t width, int32_t height);
|
||||
void reset();
|
||||
bool resize(int32_t width, int32_t height);
|
||||
FramebufferGL *framebufferGL(const gl::FramebufferState &state);
|
||||
void present();
|
||||
GLuint createGLFB(const gl::Context *context);
|
||||
FramebufferGL *framebufferGL(const gl::Context *context, const gl::FramebufferState &state);
|
||||
void present(const gl::Context *context);
|
||||
uint32_t getDRMFB();
|
||||
void bindTexImage();
|
||||
GLuint getTexture();
|
||||
int32_t getWidth() const { return mWidth; }
|
||||
int32_t getHeight() const { return mHeight; }
|
||||
GLuint getGLFB() const { return mGLFB; }
|
||||
const NativeWindow *getNative() const { return mNative; }
|
||||
|
||||
private:
|
||||
bool createRenderbuffers();
|
||||
|
||||
DisplayOzone *mDisplay;
|
||||
const NativeWindow *mNative;
|
||||
int mWidth;
|
||||
|
@ -103,7 +105,6 @@ class DisplayOzone final : public DisplayEGL
|
|||
EGLImageKHR mImage;
|
||||
GLuint mColorBuffer;
|
||||
GLuint mDSBuffer;
|
||||
GLuint mGLFB;
|
||||
GLuint mTexture;
|
||||
};
|
||||
|
||||
|
@ -148,9 +149,8 @@ class DisplayOzone final : public DisplayEGL
|
|||
egl::Error makeCurrentSurfaceless(gl::Context *context) override;
|
||||
|
||||
GLuint makeShader(GLuint type, const char *src);
|
||||
void drawBuffer(Buffer *buffer);
|
||||
void drawWithBlit(Buffer *buffer);
|
||||
void drawWithTexture(Buffer *buffer);
|
||||
void drawBuffer(const gl::Context *context, Buffer *buffer);
|
||||
void drawWithTexture(const gl::Context *context, Buffer *buffer);
|
||||
void flushGL();
|
||||
bool hasUsableScreen(int fd);
|
||||
void presentScreen();
|
||||
|
@ -161,19 +161,6 @@ class DisplayOzone final : public DisplayEGL
|
|||
void *data);
|
||||
void pageFlipHandler(unsigned int sequence, uint64_t tv);
|
||||
|
||||
// TODO(fjhenigman) Implement swap control. The following stuff will be used for that.
|
||||
enum class SwapControl
|
||||
{
|
||||
ABSENT,
|
||||
EXT,
|
||||
MESA,
|
||||
SGI,
|
||||
};
|
||||
SwapControl mSwapControl;
|
||||
int mMinSwapInterval;
|
||||
int mMaxSwapInterval;
|
||||
int mCurrentSwapInterval;
|
||||
|
||||
gbm_device *mGBM;
|
||||
drmModeConnectorPtr mConnector;
|
||||
drmModeModeInfoPtr mMode;
|
||||
|
|
|
@ -29,9 +29,10 @@ egl::Error SurfaceOzone::initialize(const egl::Display *display)
|
|||
return egl::NoError();
|
||||
}
|
||||
|
||||
FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *SurfaceOzone::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
return mBuffer->framebufferGL(state);
|
||||
return mBuffer->framebufferGL(context, state);
|
||||
}
|
||||
|
||||
egl::Error SurfaceOzone::makeCurrent()
|
||||
|
@ -41,7 +42,7 @@ egl::Error SurfaceOzone::makeCurrent()
|
|||
|
||||
egl::Error SurfaceOzone::swap(const gl::Context *context)
|
||||
{
|
||||
mBuffer->present();
|
||||
mBuffer->present(context);
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ class SurfaceOzone : public SurfaceGL
|
|||
DisplayOzone::Buffer *buffer);
|
||||
~SurfaceOzone() override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
egl::Error makeCurrent() override;
|
||||
|
|
|
@ -256,8 +256,7 @@ D3DTextureSurfaceWGL::D3DTextureSurfaceWGL(const egl::SurfaceState &state,
|
|||
mBoundObjectTextureHandle(nullptr),
|
||||
mBoundObjectRenderbufferHandle(nullptr),
|
||||
mColorRenderbufferID(0),
|
||||
mDepthStencilRenderbufferID(0),
|
||||
mFramebufferID(0)
|
||||
mDepthStencilRenderbufferID(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -284,9 +283,6 @@ D3DTextureSurfaceWGL::~D3DTextureSurfaceWGL()
|
|||
mBoundObjectTextureHandle = nullptr;
|
||||
}
|
||||
|
||||
// GL framebuffer is deleted by the default framebuffer object
|
||||
mFramebufferID = 0;
|
||||
|
||||
mDisplay->releaseD3DDevice(mDeviceHandle);
|
||||
mDeviceHandle = nullptr;
|
||||
}
|
||||
|
@ -350,21 +346,6 @@ egl::Error D3DTextureSurfaceWGL::initialize(const egl::Display *display)
|
|||
static_cast<GLsizei>(mHeight));
|
||||
}
|
||||
|
||||
mFunctionsGL->genFramebuffers(1, &mFramebufferID);
|
||||
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbufferID);
|
||||
if (config->depthSize > 0)
|
||||
{
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDepthStencilRenderbufferID);
|
||||
}
|
||||
if (config->stencilSize > 0)
|
||||
{
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, mDepthStencilRenderbufferID);
|
||||
}
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
|
@ -496,9 +477,29 @@ EGLint D3DTextureSurfaceWGL::getSwapBehavior() const
|
|||
return EGL_BUFFER_PRESERVED;
|
||||
}
|
||||
|
||||
FramebufferImpl *D3DTextureSurfaceWGL::createDefaultFramebuffer(const gl::FramebufferState &data)
|
||||
FramebufferImpl *D3DTextureSurfaceWGL::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data)
|
||||
{
|
||||
return new FramebufferGL(data, mFramebufferID, true);
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
GLuint framebufferID = 0;
|
||||
functions->genFramebuffers(1, &framebufferID);
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebufferID);
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbufferID);
|
||||
if (mState.config->depthSize > 0)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDepthStencilRenderbufferID);
|
||||
}
|
||||
if (mState.config->stencilSize > 0)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDepthStencilRenderbufferID);
|
||||
}
|
||||
|
||||
return new FramebufferGL(data, framebufferID, true);
|
||||
}
|
||||
|
||||
HDC D3DTextureSurfaceWGL::getDC() const
|
||||
|
|
|
@ -63,7 +63,8 @@ class D3DTextureSurfaceWGL : public SurfaceWGL
|
|||
EGLint isPostSubBufferSupported() const override;
|
||||
EGLint getSwapBehavior() const override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data) override;
|
||||
|
||||
HDC getDC() const override;
|
||||
|
||||
|
@ -95,7 +96,6 @@ class D3DTextureSurfaceWGL : public SurfaceWGL
|
|||
|
||||
GLuint mColorRenderbufferID;
|
||||
GLuint mDepthStencilRenderbufferID;
|
||||
GLuint mFramebufferID;
|
||||
};
|
||||
} // namespace rx
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ DXGISwapChainWindowSurfaceWGL::DXGISwapChainWindowSurfaceWGL(const egl::SurfaceS
|
|||
mColorRenderbufferID(0),
|
||||
mRenderbufferBufferHandle(nullptr),
|
||||
mDepthRenderbufferID(0),
|
||||
mFramebufferID(0),
|
||||
mTextureID(0),
|
||||
mTextureHandle(nullptr),
|
||||
mWidth(0),
|
||||
|
@ -105,9 +104,11 @@ egl::Error DXGISwapChainWindowSurfaceWGL::initialize(const egl::Display *display
|
|||
mSwapChainFlags = 0;
|
||||
mDepthBufferFormat = GL_DEPTH24_STENCIL8;
|
||||
|
||||
mFunctionsGL->genFramebuffers(1, &mFramebufferID);
|
||||
mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID);
|
||||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbufferID);
|
||||
|
||||
mFunctionsGL->genRenderbuffers(1, &mDepthRenderbufferID);
|
||||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbufferID);
|
||||
|
||||
return createSwapChain();
|
||||
}
|
||||
|
@ -268,9 +269,34 @@ EGLint DXGISwapChainWindowSurfaceWGL::getSwapBehavior() const
|
|||
}
|
||||
|
||||
FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer(
|
||||
const gl::Context *context,
|
||||
const gl::FramebufferState &data)
|
||||
{
|
||||
return new FramebufferGL(data, mFramebufferID, true);
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
StateManagerGL *stateManager = GetStateManagerGL(context);
|
||||
|
||||
GLuint framebufferID = 0;
|
||||
stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebufferID);
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbufferID);
|
||||
|
||||
if (mDepthBufferFormat != GL_NONE)
|
||||
{
|
||||
const gl::InternalFormat &depthStencilFormatInfo =
|
||||
gl::GetSizedInternalFormatInfo(mDepthBufferFormat);
|
||||
if (depthStencilFormatInfo.depthBits > 0)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mDepthRenderbufferID);
|
||||
}
|
||||
if (depthStencilFormatInfo.stencilBits > 0)
|
||||
{
|
||||
functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, mDepthRenderbufferID);
|
||||
}
|
||||
}
|
||||
|
||||
return new FramebufferGL(data, framebufferID, true);
|
||||
}
|
||||
|
||||
HDC DXGISwapChainWindowSurfaceWGL::getDC() const
|
||||
|
@ -470,7 +496,6 @@ egl::Error DXGISwapChainWindowSurfaceWGL::createSwapChain()
|
|||
<< gl::FmtHR(result);
|
||||
}
|
||||
|
||||
mFunctionsGL->genRenderbuffers(1, &mColorRenderbufferID);
|
||||
mStateManager->bindRenderbuffer(GL_RENDERBUFFER, mColorRenderbufferID);
|
||||
mRenderbufferBufferHandle =
|
||||
mFunctionsWGL->dxRegisterObjectNV(mDeviceHandle, colorBuffer, mColorRenderbufferID,
|
||||
|
@ -500,11 +525,6 @@ egl::Error DXGISwapChainWindowSurfaceWGL::createSwapChain()
|
|||
return error;
|
||||
}
|
||||
|
||||
ASSERT(mFramebufferID != 0);
|
||||
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||
mColorRenderbufferID);
|
||||
|
||||
if (mDepthBufferFormat != GL_NONE)
|
||||
{
|
||||
ASSERT(mDepthRenderbufferID != 0);
|
||||
|
@ -512,19 +532,6 @@ egl::Error DXGISwapChainWindowSurfaceWGL::createSwapChain()
|
|||
mFunctionsGL->renderbufferStorage(GL_RENDERBUFFER, mDepthBufferFormat,
|
||||
static_cast<GLsizei>(mWidth),
|
||||
static_cast<GLsizei>(mHeight));
|
||||
|
||||
const gl::InternalFormat &depthStencilFormatInfo =
|
||||
gl::GetSizedInternalFormatInfo(mDepthBufferFormat);
|
||||
if (depthStencilFormatInfo.depthBits > 0)
|
||||
{
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, mDepthRenderbufferID);
|
||||
}
|
||||
if (depthStencilFormatInfo.stencilBits > 0)
|
||||
{
|
||||
mFunctionsGL->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, mDepthRenderbufferID);
|
||||
}
|
||||
}
|
||||
|
||||
mFirstSwap = true;
|
||||
|
|
|
@ -59,7 +59,8 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceWGL
|
|||
EGLint isPostSubBufferSupported() const override;
|
||||
EGLint getSwapBehavior() const override;
|
||||
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &data) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &data) override;
|
||||
|
||||
HDC getDC() const override;
|
||||
|
||||
|
@ -93,8 +94,6 @@ class DXGISwapChainWindowSurfaceWGL : public SurfaceWGL
|
|||
|
||||
GLuint mDepthRenderbufferID;
|
||||
|
||||
GLuint mFramebufferID;
|
||||
|
||||
GLuint mTextureID;
|
||||
HANDLE mTextureHandle;
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ egl::Error SurfaceNULL::initialize(const egl::Display *display)
|
|||
return egl::NoError();
|
||||
}
|
||||
|
||||
FramebufferImpl *SurfaceNULL::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *SurfaceNULL::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
return new FramebufferNULL(state);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ class SurfaceNULL : public SurfaceImpl
|
|||
~SurfaceNULL() override;
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
egl::Error swap(const gl::Context *context) override;
|
||||
egl::Error postSubBuffer(const gl::Context *context,
|
||||
EGLint x,
|
||||
|
|
|
@ -66,7 +66,8 @@ egl::Error OffscreenSurfaceVk::initialize(const egl::Display *display)
|
|||
return egl::NoError();
|
||||
}
|
||||
|
||||
FramebufferImpl *OffscreenSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *OffscreenSurfaceVk::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
// Use a user FBO for an offscreen RT.
|
||||
return FramebufferVk::CreateUserFBO(state);
|
||||
|
@ -442,7 +443,8 @@ vk::Error WindowSurfaceVk::initializeImpl(RendererVk *renderer)
|
|||
return vk::NoError();
|
||||
}
|
||||
|
||||
FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::FramebufferState &state)
|
||||
FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state)
|
||||
{
|
||||
return FramebufferVk::CreateDefaultFBO(state, this);
|
||||
}
|
||||
|
|
|
@ -27,7 +27,8 @@ class OffscreenSurfaceVk : public SurfaceImpl
|
|||
~OffscreenSurfaceVk() override;
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
egl::Error swap(const gl::Context *context) override;
|
||||
egl::Error postSubBuffer(const gl::Context *context,
|
||||
EGLint x,
|
||||
|
@ -74,7 +75,8 @@ class WindowSurfaceVk : public SurfaceImpl, public vk::CommandGraphResource
|
|||
void destroy(const egl::Display *display) override;
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override;
|
||||
FramebufferImpl *createDefaultFramebuffer(const gl::Context *context,
|
||||
const gl::FramebufferState &state) override;
|
||||
egl::Error swap(const gl::Context *context) override;
|
||||
egl::Error postSubBuffer(const gl::Context *context,
|
||||
EGLint x,
|
||||
|
|
Загрузка…
Ссылка в новой задаче