--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -800,16 +800,18 @@ WebGLContext::ResizeBackbuffer(uint32_t
width /= 2;
height /= 2;
}
if (!resized)
return false;
+ RebindFramebuffers();
+
mWidth = gl->OffscreenSize().width;
mHeight = gl->OffscreenSize().height;
MOZ_ASSERT((uint32_t)mWidth == width);
MOZ_ASSERT((uint32_t)mHeight == height);
if (width != requestedWidth ||
height != requestedHeight)
{
@@ -817,16 +819,36 @@ WebGLContext::ResizeBackbuffer(uint32_t
" to %dx%d succeeded.",
requestedWidth, requestedHeight,
width, height);
}
return true;
}
void
+WebGLContext::RebindFramebuffers() const
+{
+ const auto fnBind = [&](const GLenum target, const WebGLFramebuffer* const fb) {
+ if (fb) {
+ gl->fBindFramebuffer(target, fb->mGLName);
+ } else {
+ gl->Screen()->BindAsFramebuffer(target);
+ }
+ };
+
+ if (IsWebGL2()) {
+ fnBind(LOCAL_GL_DRAW_FRAMEBUFFER, mBoundDrawFramebuffer);
+ fnBind(LOCAL_GL_READ_FRAMEBUFFER, mBoundReadFramebuffer);
+ } else {
+ MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
+ fnBind(LOCAL_GL_FRAMEBUFFER, mBoundDrawFramebuffer);
+ }
+}
+
+void
WebGLContext::ThrowEvent_WebGLContextCreationError(const nsACString& text)
{
RefPtr<EventTarget> target = mCanvasElement;
if (!target && mOffscreenCanvas) {
target = mOffscreenCanvas;
} else if (!target) {
GenerateWarning("Failed to create WebGL context: %s", text.BeginReading());
return;
@@ -1088,17 +1110,17 @@ WebGLContext::SetDimensions(int32_t sign
MakeContextCurrent();
gl->fViewport(0, 0, mWidth, mHeight);
mViewportX = mViewportY = 0;
mViewportWidth = mWidth;
mViewportHeight = mHeight;
gl->fScissor(0, 0, mWidth, mHeight);
- gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+ gl->Screen()->BindAsFramebuffer();
//////
// Check everything
AssertCachedBindings();
AssertCachedGlobalState();
MOZ_ASSERT(gl->Caps().color);
@@ -1477,17 +1499,18 @@ WebGLContext::MozGetUnderlyingParamStrin
return NS_OK;
}
void
WebGLContext::ClearScreen()
{
MakeContextCurrent();
- ScopedBindFramebuffer autoFB(gl, 0);
+ ScopedBindFramebuffer autoFB(gl);
+ gl->Screen()->BindAsFramebuffer();
const bool changeDrawBuffers = (mDefaultFB_DrawBuffer0 != LOCAL_GL_BACK);
if (changeDrawBuffers) {
gl->Screen()->SetDrawBuffer(LOCAL_GL_BACK);
}
GLbitfield bufferBits = LOCAL_GL_COLOR_BUFFER_BIT;
if (mOptions.depth)
@@ -1610,16 +1633,17 @@ WebGLContext::PresentScreenBuffer()
GLScreenBuffer* screen = gl->Screen();
MOZ_ASSERT(screen);
if (!screen->PublishFrame(screen->Size())) {
ForceLoseContext();
return false;
}
+ RebindFramebuffers();
if (!mOptions.preserveDrawingBuffer) {
mBackbufferNeedsClear = true;
}
mShouldPresent = false;
OnEndOfFrame();
@@ -1949,17 +1973,18 @@ WebGLContext::GetSurfaceSnapshot(gfxAlph
surf = Factory::CreateDataSourceSurfaceWithStride(IntSize(mWidth, mHeight),
surfFormat,
mWidth * 4);
if (NS_WARN_IF(!surf))
return nullptr;
gl->MakeCurrent();
{
- ScopedBindFramebuffer autoFB(gl, 0);
+ ScopedBindFramebuffer autoFB(gl);
+ gl->Screen()->BindAsFramebuffer();
ClearBackbufferIfNeeded();
// Save, override, then restore glReadBuffer.
const GLenum readBufferMode = gl->Screen()->GetReadBufferMode();
if (readBufferMode != LOCAL_GL_BACK) {
gl->Screen()->SetReadBuffer(LOCAL_GL_BACK);
}
@@ -2176,34 +2201,16 @@ ScopedUnpackReset::UnwrapImpl()
}
mGL->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, pbo);
}
}
////////////////////
-void
-ScopedFBRebinder::UnwrapImpl()
-{
- const auto fnName = [&](WebGLFramebuffer* fb) {
- return fb ? fb->mGLName : 0;
- };
-
- if (mWebGL->IsWebGL2()) {
- mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, fnName(mWebGL->mBoundDrawFramebuffer));
- mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, fnName(mWebGL->mBoundReadFramebuffer));
- } else {
- MOZ_ASSERT(mWebGL->mBoundDrawFramebuffer == mWebGL->mBoundReadFramebuffer);
- mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fnName(mWebGL->mBoundDrawFramebuffer));
- }
-}
-
-////////////////////
-
static GLenum
TargetIfLazy(GLenum target)
{
switch (target) {
case LOCAL_GL_PIXEL_PACK_BUFFER:
case LOCAL_GL_PIXEL_UNPACK_BUFFER:
return target;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -1887,16 +1887,18 @@ protected:
uint8_t bytesPerPixel, uint32_t* const out_rowStride,
uint32_t* const out_endOffset);
GLenum mPixelStore_ColorspaceConversion;
bool mPixelStore_FlipY;
bool mPixelStore_PremultiplyAlpha;
bool mPixelStore_RequireFastPath;
+ void RebindFramebuffers() const;
+
////////////////////////////////////
class FakeBlackTexture {
public:
static UniquePtr<FakeBlackTexture> Create(gl::GLContext* gl,
TexTarget target,
FakeBlackType type);
gl::GLContext* const mGL;
const GLuint mGLName;
@@ -2159,17 +2161,19 @@ private:
public:
explicit ScopedFBRebinder(WebGLContext* webgl)
: ScopedGLWrapper<ScopedFBRebinder>(webgl->gl)
, mWebGL(webgl)
{ }
private:
- void UnwrapImpl();
+ void UnwrapImpl() {
+ mWebGL->RebindFramebuffers();
+ }
};
class ScopedLazyBind final
: public gl::ScopedGLWrapper<ScopedLazyBind>
{
friend struct gl::ScopedGLWrapper<ScopedLazyBind>;
const GLenum mTarget;
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -136,20 +136,19 @@ WebGLContext::BindFramebuffer(GLenum tar
return;
if (wfb && !ValidateObject("bindFramebuffer", *wfb))
return;
MakeContextCurrent();
if (!wfb) {
- gl->fBindFramebuffer(target, 0);
+ gl->Screen()->BindAsFramebuffer(target);
} else {
- GLuint framebuffername = wfb->mGLName;
- gl->fBindFramebuffer(target, framebuffername);
+ gl->fBindFramebuffer(target, wfb->mGLName);
#ifdef ANDROID
wfb->mIsFB = true;
#endif
}
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
mBoundDrawFramebuffer = wfb;
@@ -157,17 +156,17 @@ WebGLContext::BindFramebuffer(GLenum tar
break;
case LOCAL_GL_DRAW_FRAMEBUFFER:
mBoundDrawFramebuffer = wfb;
break;
case LOCAL_GL_READ_FRAMEBUFFER:
mBoundReadFramebuffer = wfb;
break;
default:
- break;
+ MOZ_CRASH();
}
}
void
WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer* wrb)
{
if (IsContextLost())
return;
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -747,28 +747,26 @@ WebGLContext::AssertCachedBindings()
GetAndFlushUnderlyingGLErrors();
if (IsWebGL2() || IsExtensionEnabled(WebGLExtensionID::OES_vertex_array_object)) {
GLuint bound = mBoundVertexArray ? mBoundVertexArray->GLName() : 0;
AssertUintParamCorrect(gl, LOCAL_GL_VERTEX_ARRAY_BINDING, bound);
}
// Framebuffers
- if (IsWebGL2()) {
- GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
- : 0;
- AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, bound);
-
- bound = mBoundReadFramebuffer ? mBoundReadFramebuffer->mGLName : 0;
- AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, bound);
+ const auto boundDrawFB = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
+ : gl->Screen()->DrawFB();
+ const auto boundReadFB = mBoundReadFramebuffer ? mBoundReadFramebuffer->mGLName
+ : gl->Screen()->ReadFB();
+ if (gl->IsSupported(GLFeature::split_framebuffer)) {
+ AssertUintParamCorrect(gl, LOCAL_GL_DRAW_FRAMEBUFFER_BINDING, boundDrawFB);
+ AssertUintParamCorrect(gl, LOCAL_GL_READ_FRAMEBUFFER_BINDING, boundReadFB);
} else {
MOZ_ASSERT(mBoundDrawFramebuffer == mBoundReadFramebuffer);
- GLuint bound = mBoundDrawFramebuffer ? mBoundDrawFramebuffer->mGLName
- : 0;
- AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, bound);
+ AssertUintParamCorrect(gl, LOCAL_GL_FRAMEBUFFER_BINDING, boundDrawFB);
}
GLint stencilBits = 0;
if (GetStencilBits(&stencilBits)) { // Depends on current draw framebuffer.
const GLuint stencilRefMask = (1 << stencilBits) - 1;
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_REF, stencilRefMask, mStencilRefFront);
AssertMaskedUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_REF, stencilRefMask, mStencilRefBack);
--- a/dom/canvas/WebGLTextureUpload.cpp
+++ b/dom/canvas/WebGLTextureUpload.cpp
@@ -1712,16 +1712,17 @@ ValidateCopyTexImageFormats(WebGLContext
////////////////////////////////////////////////////////////////////////////////
class ScopedCopyTexImageSource
{
WebGLContext* const mWebGL;
GLuint mRB;
GLuint mFB;
+ UniquePtr<gl::ScopedBindFramebuffer> mBindFB;
public:
ScopedCopyTexImageSource(WebGLContext* webgl, const char* funcName, uint32_t srcWidth,
uint32_t srcHeight, const webgl::FormatInfo* srcFormat,
const webgl::FormatUsageInfo* dstUsage);
~ScopedCopyTexImageSource();
};
@@ -1814,17 +1815,17 @@ ScopedCopyTexImageSource::ScopedCopyTexI
GLuint rgbaRB = 0;
gl->fGenRenderbuffers(1, &rgbaRB);
gl::ScopedBindRenderbuffer scopedRB(gl, rgbaRB);
gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, sizedFormat, srcWidth, srcHeight);
GLuint rgbaFB = 0;
gl->fGenFramebuffers(1, &rgbaFB);
- gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, rgbaFB);
+ mBindFB.reset(new gl::ScopedBindFramebuffer(gl, rgbaFB));
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER, rgbaRB);
const GLenum status = gl->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
MOZ_CRASH("GFX: Temp framebuffer is not complete.");
}
@@ -1840,40 +1841,26 @@ ScopedCopyTexImageSource::ScopedCopyTexI
scopedBindTex.Unwrap();
scopedTex.Unwrap();
// Leave RB and FB alive, and FB bound.
mRB = rgbaRB;
mFB = rgbaFB;
}
-template<typename T>
-static inline GLenum
-ToGLHandle(const T& obj)
-{
- return (obj ? obj->mGLName : 0);
-}
-
ScopedCopyTexImageSource::~ScopedCopyTexImageSource()
{
if (!mFB) {
MOZ_ASSERT(!mRB);
return;
}
MOZ_ASSERT(mRB);
gl::GLContext* gl = mWebGL->gl;
- // If we're swizzling, it's because we're on a GL core (3.2+) profile, which has
- // split framebuffer support.
- gl->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER,
- ToGLHandle(mWebGL->mBoundDrawFramebuffer));
- gl->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER,
- ToGLHandle(mWebGL->mBoundReadFramebuffer));
-
gl->fDeleteFramebuffers(1, &mFB);
gl->fDeleteRenderbuffers(1, &mRB);
}
////////////////////////////////////////////////////////////////////////////////
static bool
GetUnsizedFormatForCopy(GLenum internalFormat, webgl::UnsizedFormat* const out)
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -548,68 +548,36 @@ GLBlitHelper::DeleteTexBlitProgram()
mGL->fDeleteProgram(mTexNV12PlanarBlit_Program);
mTexNV12PlanarBlit_Program = 0;
}
}
void
GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
const gfx::IntSize& srcSize,
- const gfx::IntSize& destSize,
- bool internalFBs)
+ const gfx::IntSize& destSize)
{
MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
ScopedBindFramebuffer boundFB(mGL);
- ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
+ mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, srcFB);
+ mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFB);
- if (internalFBs) {
- mGL->Screen()->BindReadFB_Internal(srcFB);
- mGL->Screen()->BindDrawFB_Internal(destFB);
- } else {
- mGL->BindReadFB(srcFB);
- mGL->BindDrawFB(destFB);
- }
+ ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
mGL->fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
0, 0, destSize.width, destSize.height,
LOCAL_GL_COLOR_BUFFER_BIT,
LOCAL_GL_NEAREST);
}
void
-GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
- const gfx::IntSize& srcSize,
- const gfx::IntSize& destSize,
- const GLFormats& srcFormats,
- bool internalFBs)
-{
- MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
- MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
-
- if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
- BlitFramebufferToFramebuffer(srcFB, destFB,
- srcSize, destSize,
- internalFBs);
- return;
- }
-
- GLuint tex = CreateTextureForOffscreen(mGL, srcFormats, srcSize);
- MOZ_ASSERT(tex);
-
- BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize, internalFBs);
- BlitTextureToFramebuffer(tex, destFB, srcSize, destSize, internalFBs);
-
- mGL->fDeleteTextures(1, &tex);
-}
-
-void
GLBlitHelper::BindAndUploadYUVTexture(Channel which,
uint32_t width,
uint32_t height,
void* data,
bool needsAllocation)
{
MOZ_ASSERT(which < Channel_Max, "Invalid channel!");
GLuint* srcTexArr[3] = {&mSrcTexY, &mSrcTexCb, &mSrcTexCr};
@@ -888,64 +856,54 @@ GLBlitHelper::BlitImageToTexture(layers:
return BlitImageToFramebuffer(srcImage, destSize, autoFBForTex.FB(), destOrigin);
}
void
GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum srcTarget,
- bool internalFBs)
+ GLenum srcTarget)
{
MOZ_ASSERT(mGL->fIsTexture(srcTex));
MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB));
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget);
MOZ_DIAGNOSTIC_ASSERT(srcWrapper.IsComplete());
- BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB,
- srcSize, destSize,
- internalFBs);
+ BlitFramebufferToFramebuffer(srcWrapper.FB(), destFB, srcSize, destSize);
return;
}
- DrawBlitTextureToFramebuffer(srcTex, destFB, srcSize, destSize, srcTarget,
- internalFBs);
+ DrawBlitTextureToFramebuffer(srcTex, destFB, srcSize, destSize, srcTarget);
}
void
GLBlitHelper::DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum srcTarget,
- bool internalFBs)
+ GLenum srcTarget)
{
BlitType type;
switch (srcTarget) {
case LOCAL_GL_TEXTURE_2D:
type = BlitTex2D;
break;
case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
type = BlitTexRect;
break;
default:
MOZ_CRASH("GFX: Fatal Error: Bad `srcTarget`.");
break;
}
ScopedGLDrawState autoStates(mGL);
- const ScopedBindFramebuffer bindFB(mGL);
- if (internalFBs) {
- mGL->Screen()->BindFB_Internal(destFB);
- } else {
- mGL->BindFB(destFB);
- }
+ const ScopedBindFramebuffer bindFB(mGL, destFB);
// Does destructive things to (only!) what we just saved above.
bool good = UseTexQuadProgram(type, srcSize);
if (!good) {
// We're up against the wall, so bail.
MOZ_DIAGNOSTIC_ASSERT(false,
"Error: Failed to prepare to blit texture->framebuffer.\n");
mGL->fScissor(0, 0, destSize.width, destSize.height);
@@ -957,40 +915,33 @@ GLBlitHelper::DrawBlitTextureToFramebuff
const ScopedBindTexture bindTex(mGL, srcTex, srcTarget);
mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
}
void
GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum destTarget,
- bool internalFBs)
+ GLenum destTarget)
{
// On the Android 4.3 emulator, IsFramebuffer may return false incorrectly.
MOZ_ASSERT_IF(mGL->Renderer() != GLRenderer::AndroidEmulator, !srcFB || mGL->fIsFramebuffer(srcFB));
MOZ_ASSERT(mGL->fIsTexture(destTex));
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
ScopedFramebufferForTexture destWrapper(mGL, destTex, destTarget);
BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(),
- srcSize, destSize,
- internalFBs);
+ srcSize, destSize);
return;
}
ScopedBindTexture autoTex(mGL, destTex, destTarget);
- ScopedBindFramebuffer boundFB(mGL);
- if (internalFBs) {
- mGL->Screen()->BindFB_Internal(srcFB);
- } else {
- mGL->BindFB(srcFB);
- }
+ ScopedBindFramebuffer boundFB(mGL, srcFB);
ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
mGL->fCopyTexSubImage2D(destTarget, 0,
0, 0,
0, 0,
srcSize.width, srcSize.height);
}
--- a/gfx/gl/GLBlitHelper.h
+++ b/gfx/gl/GLBlitHelper.h
@@ -120,38 +120,29 @@ class GLBlitHelper final
public:
~GLBlitHelper();
// If you don't have |srcFormats| for the 2nd definition,
// then you'll need the framebuffer_blit extensions to use
// the first BlitFramebufferToFramebuffer.
void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
const gfx::IntSize& srcSize,
- const gfx::IntSize& destSize,
- bool internalFBs = false);
- void BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB,
- const gfx::IntSize& srcSize,
- const gfx::IntSize& destSize,
- const GLFormats& srcFormats,
- bool internalFBs = false);
+ const gfx::IntSize& destSize);
void BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
- bool internalFBs = false);
+ GLenum srcTarget = LOCAL_GL_TEXTURE_2D);
void DrawBlitTextureToFramebuffer(GLuint srcTex, GLuint destFB,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
- bool internalFBs = false);
+ GLenum srcTarget = LOCAL_GL_TEXTURE_2D);
void BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
- GLenum destTarget = LOCAL_GL_TEXTURE_2D,
- bool internalFBs = false);
+ GLenum destTarget = LOCAL_GL_TEXTURE_2D);
void BlitTextureToTexture(GLuint srcTex, GLuint destTex,
const gfx::IntSize& srcSize,
const gfx::IntSize& destSize,
GLenum srcTarget = LOCAL_GL_TEXTURE_2D,
GLenum destTarget = LOCAL_GL_TEXTURE_2D);
bool BlitImageToFramebuffer(layers::Image* srcImage, const gfx::IntSize& destSize,
GLuint destFB, OriginPos destOrigin);
bool BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize,
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -960,17 +960,16 @@ GLContext::InitWithPrefixImpl(const char
if (IsSupported(GLFeature::framebuffer_multisample)) {
fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&mMaxSamples);
}
////////////////////////////////////////////////////////////////////////////
// We're ready for final setup.
- fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
// TODO: Remove SurfaceCaps::any.
if (mCaps.any) {
mCaps.any = false;
mCaps.color = true;
mCaps.alpha = false;
}
@@ -1960,36 +1959,36 @@ GLContext::AssembleOffscreenFBs(const GL
ScopedBindFramebuffer autoFB(this);
GLuint drawFB = 0;
GLuint readFB = 0;
if (texture) {
readFB = 0;
fGenFramebuffers(1, &readFB);
- BindFB(readFB);
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, readFB);
fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_TEXTURE_2D,
texture,
0);
}
if (colorMSRB) {
drawFB = 0;
fGenFramebuffers(1, &drawFB);
- BindFB(drawFB);
+ fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, drawFB);
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_COLOR_ATTACHMENT0,
LOCAL_GL_RENDERBUFFER,
colorMSRB);
} else {
drawFB = readFB;
}
- MOZ_ASSERT(GetFB() == drawFB);
+ MOZ_ASSERT(GetIntAs<GLuint>(LOCAL_GL_FRAMEBUFFER_BINDING) == drawFB);
if (depthRB) {
fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER,
LOCAL_GL_DEPTH_ATTACHMENT,
LOCAL_GL_RENDERBUFFER,
depthRB);
}
@@ -2358,64 +2357,43 @@ GLContext::GuaranteeResolve()
const gfx::IntSize&
GLContext::OffscreenSize() const
{
MOZ_ASSERT(IsOffscreen());
return mScreen->Size();
}
bool
-GLContext::CreateScreenBufferImpl(const IntSize& size, const SurfaceCaps& caps)
+GLContext::CreateScreenBuffer(const IntSize& size, const SurfaceCaps& caps)
{
+ if (!IsOffscreenSizeAllowed(size))
+ return false;
+
UniquePtr<GLScreenBuffer> newScreen = GLScreenBuffer::Create(this, size, caps);
if (!newScreen)
return false;
if (!newScreen->Resize(size)) {
return false;
}
- // This will rebind to 0 (Screen) if needed when
- // it falls out of scope.
- ScopedBindFramebuffer autoFB(this);
-
mScreen = Move(newScreen);
return true;
}
bool
GLContext::ResizeScreenBuffer(const IntSize& size)
{
if (!IsOffscreenSizeAllowed(size))
return false;
return mScreen->Resize(size);
}
-void
-GLContext::ForceDirtyScreen()
-{
- ScopedBindFramebuffer autoFB(0);
-
- BeforeGLDrawCall();
- // no-op; just pretend we did something
- AfterGLDrawCall();
-}
-
-void
-GLContext::CleanDirtyScreen()
-{
- ScopedBindFramebuffer autoFB(0);
-
- BeforeGLReadCall();
- // no-op; we just want to make sure the Read FBO is updated if it needs to be
- AfterGLReadCall();
-}
-
bool
GLContext::IsOffscreenSizeAllowed(const IntSize& aSize) const
{
int32_t biggerDimension = std::max(aSize.width, aSize.height);
int32_t maxAllowed = std::min(mMaxRenderbufferSize, mMaxTextureSize);
return biggerDimension <= maxAllowed;
}
@@ -2539,17 +2517,17 @@ GLContext::Readback(SharedSurface* src,
{
ScopedBindFramebuffer autoFB(this);
// We're consuming from the producer side, so which do we use?
// Really, we just want a read-only lock, so ConsumerAcquire is the best match.
src->ProducerReadAcquire();
if (src->mAttachType == AttachmentType::Screen) {
- fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+ mScreen->BindAsFramebuffer();
} else {
fGenFramebuffers(1, &tempFB);
fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, tempFB);
switch (src->mAttachType) {
case AttachmentType::GLTexture:
fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
src->ProdTextureTarget(), src->ProdTexture(), 0);
@@ -2616,47 +2594,29 @@ GLContext::AfterGLDrawCall()
mHeavyGLCallsSinceLastFlush = true;
}
// Do whatever setup is necessary to read from our offscreen FBO, if it's
// bound.
void
GLContext::BeforeGLReadCall()
{
- if (mScreen)
+ if (mScreen) {
mScreen->BeforeReadCall();
+ }
}
void
GLContext::fBindFramebuffer(GLenum target, GLuint framebuffer)
{
- if (!mScreen) {
- raw_fBindFramebuffer(target, framebuffer);
- return;
+ raw_fBindFramebuffer(target, framebuffer);
+
+ if (mScreen) {
+ mScreen->OnBindFramebuffer(target, framebuffer);
}
-
- switch (target) {
- case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
- mScreen->BindDrawFB(framebuffer);
- return;
-
- case LOCAL_GL_READ_FRAMEBUFFER_EXT:
- mScreen->BindReadFB(framebuffer);
- return;
-
- case LOCAL_GL_FRAMEBUFFER:
- mScreen->BindFB(framebuffer);
- return;
-
- default:
- // Nothing we care about, likely an error.
- break;
- }
-
- raw_fBindFramebuffer(target, framebuffer);
}
void
GLContext::fCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border)
{
if (!IsTextureSizeSafeToPassToDriver(target, width, height)) {
// pass wrong values to cause the GL to generate GL_INVALID_VALUE.
@@ -2680,35 +2640,16 @@ GLContext::fCopyTexImage2D(GLenum target
}
AfterGLReadCall();
}
void
GLContext::fGetIntegerv(GLenum pname, GLint* params)
{
switch (pname) {
- // LOCAL_GL_FRAMEBUFFER_BINDING is equal to
- // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT,
- // so we don't need two cases.
- case LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT:
- if (mScreen) {
- *params = mScreen->GetDrawFB();
- } else {
- raw_fGetIntegerv(pname, params);
- }
- break;
-
- case LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT:
- if (mScreen) {
- *params = mScreen->GetReadFB();
- } else {
- raw_fGetIntegerv(pname, params);
- }
- break;
-
case LOCAL_GL_MAX_TEXTURE_SIZE:
MOZ_ASSERT(mMaxTextureSize>0);
*params = mMaxTextureSize;
break;
case LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE:
MOZ_ASSERT(mMaxCubeMapTextureSize>0);
*params = mMaxCubeMapTextureSize;
@@ -2786,17 +2727,17 @@ GLContext::fReadPixels(GLint x, GLint y,
void
GLContext::fDeleteFramebuffers(GLsizei n, const GLuint* names)
{
if (mScreen) {
// Notify mScreen which framebuffers we're deleting.
// Otherwise, we will get framebuffer binding mispredictions.
for (int i = 0; i < n; i++) {
- mScreen->DeletingFB(names[i]);
+ mScreen->OnDeleteFramebuffer(names[i]);
}
}
// Avoid crash by flushing before glDeleteFramebuffers. See bug 1194923.
if (mNeedsFlushBeforeDeleteFB) {
fFlush();
}
@@ -2852,67 +2793,27 @@ GLContext::fTexImage2D(GLenum target, GL
if (!WillTextureMapSucceed(width, height, internalformat, type)) {
return;
}
}
#endif
raw_fTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
}
-GLuint
-GLContext::GetDrawFB()
-{
- if (mScreen)
- return mScreen->GetDrawFB();
-
- GLuint ret = 0;
- GetUIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, &ret);
- return ret;
-}
-
-GLuint
-GLContext::GetReadFB()
-{
- if (mScreen)
- return mScreen->GetReadFB();
-
- GLenum bindEnum = IsSupported(GLFeature::split_framebuffer)
- ? LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT
- : LOCAL_GL_FRAMEBUFFER_BINDING;
-
- GLuint ret = 0;
- GetUIntegerv(bindEnum, &ret);
- return ret;
-}
-
-GLuint
-GLContext::GetFB()
-{
- if (mScreen) {
- // This has a very important extra assert that checks that we're
- // not accidentally ignoring a situation where the draw and read
- // FBs differ.
- return mScreen->GetFB();
- }
-
- GLuint ret = 0;
- GetUIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, &ret);
- return ret;
-}
-
bool
GLContext::InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps)
{
if (!CreateScreenBuffer(size, caps))
return false;
- if (!MakeCurrent()) {
+ if (!MakeCurrent())
return false;
- }
- fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
+
+ mScreen->BindAsFramebuffer();
+
fScissor(0, 0, size.width, size.height);
fViewport(0, 0, size.width, size.height);
mCaps = mScreen->mCaps;
MOZ_ASSERT(!mCaps.any);
return true;
}
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -3335,35 +3335,16 @@ public:
/*
* Return size of this offscreen context.
*
* Only valid if IsOffscreen() returns true.
*/
const gfx::IntSize& OffscreenSize() const;
- void BindFB(GLuint fb) {
- fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
- MOZ_ASSERT(!fb || fIsFramebuffer(fb));
- }
-
- void BindDrawFB(GLuint fb) {
- fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
- }
-
- void BindReadFB(GLuint fb) {
- fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
- }
-
- GLuint GetDrawFB();
-
- GLuint GetReadFB();
-
- GLuint GetFB();
-
private:
void GetShaderPrecisionFormatNonES2(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
switch (precisiontype) {
case LOCAL_GL_LOW_FLOAT:
case LOCAL_GL_MEDIUM_FLOAT:
case LOCAL_GL_HIGH_FLOAT:
// Assume IEEE 754 precision
range[0] = 127;
@@ -3378,20 +3359,16 @@ private:
range[0] = 24;
range[1] = 24;
*precision = 0;
break;
}
}
public:
-
- void ForceDirtyScreen();
- void CleanDirtyScreen();
-
virtual GLenum GetPreferredARGB32Format() const { return LOCAL_GL_RGBA; }
virtual GLenum GetPreferredEGLImageTextureTarget() const {
return IsExtensionSupported(OES_EGL_image_external) ?
LOCAL_GL_TEXTURE_EXTERNAL : LOCAL_GL_TEXTURE_2D;
}
virtual bool RenewSurface(widget::CompositorWidget* aWidget) { return false; }
@@ -3453,25 +3430,17 @@ public:
return thisShared == otherShared;
}
bool InitOffscreen(const gfx::IntSize& size, const SurfaceCaps& caps);
protected:
// Note that it does -not- clear the resized buffers.
- bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps) {
- if (!IsOffscreenSizeAllowed(size))
- return false;
-
- return CreateScreenBufferImpl(size, caps);
- }
-
- bool CreateScreenBufferImpl(const gfx::IntSize& size,
- const SurfaceCaps& caps);
+ bool CreateScreenBuffer(const gfx::IntSize& size, const SurfaceCaps& caps);
public:
bool ResizeScreenBuffer(const gfx::IntSize& size);
protected:
SurfaceCaps mCaps;
public:
--- a/gfx/gl/GLScreenBuffer.cpp
+++ b/gfx/gl/GLScreenBuffer.cpp
@@ -141,267 +141,121 @@ GLScreenBuffer::GLScreenBuffer(GLContext
const SurfaceCaps& caps,
UniquePtr<SurfaceFactory> factory)
: mGL(gl)
, mCaps(caps)
, mFactory(Move(factory))
, mNeedsBlit(true)
, mUserReadBufferMode(LOCAL_GL_BACK)
, mUserDrawBufferMode(LOCAL_GL_BACK)
- , mUserDrawFB(0)
- , mUserReadFB(0)
- , mInternalDrawFB(0)
- , mInternalReadFB(0)
-#ifdef DEBUG
- , mInInternalMode_DrawFB(true)
- , mInInternalMode_ReadFB(true)
-#endif
+ , mBoundDrawFB(0)
+ , mBoundReadFB(0)
{ }
GLScreenBuffer::~GLScreenBuffer()
{
mFactory = nullptr;
mDraw = nullptr;
mRead = nullptr;
if (!mBack)
return;
// Detach mBack cleanly.
mBack->Surf()->ProducerRelease();
}
void
-GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
+GLScreenBuffer::BindAsFramebuffer(const GLenum target) const
{
- GLuint drawFB = DrawFB();
- GLuint readFB = ReadFB();
-
- if (!gl->IsSupported(GLFeature::split_framebuffer)) {
- MOZ_ASSERT(drawFB == readFB);
- gl->raw_fBindFramebuffer(target, readFB);
- return;
- }
+ const auto drawFB = DrawFB();
+ const auto readFB = ReadFB();
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
- gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
- gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
+ if (drawFB == readFB) {
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, readFB);
+ } else {
+ mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
+ mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
+ }
break;
case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
- gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
+ mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
break;
case LOCAL_GL_READ_FRAMEBUFFER_EXT:
- gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
+ mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
break;
default:
MOZ_CRASH("GFX: Bad `target` for BindFramebuffer.");
}
}
void
-GLScreenBuffer::BindFB(GLuint fb)
+GLScreenBuffer::OnBindFramebuffer(const GLenum target, const GLuint fb)
{
- GLuint drawFB = DrawFB();
- GLuint readFB = ReadFB();
-
- mUserDrawFB = fb;
- mUserReadFB = fb;
- mInternalDrawFB = (fb == 0) ? drawFB : fb;
- mInternalReadFB = (fb == 0) ? readFB : fb;
-
- if (mInternalDrawFB == mInternalReadFB) {
- mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
- } else {
- MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
- mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
- mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
- }
-
-#ifdef DEBUG
- mInInternalMode_DrawFB = false;
- mInInternalMode_ReadFB = false;
-#endif
-}
-
-void
-GLScreenBuffer::BindDrawFB(GLuint fb)
-{
- MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
-
- GLuint drawFB = DrawFB();
- mUserDrawFB = fb;
- mInternalDrawFB = (fb == 0) ? drawFB : fb;
-
- mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
-
-#ifdef DEBUG
- mInInternalMode_DrawFB = false;
-#endif
-}
+ switch (target) {
+ case LOCAL_GL_FRAMEBUFFER:
+ mBoundDrawFB = fb;
+ mBoundReadFB = fb;
+ break;
-void
-GLScreenBuffer::BindReadFB(GLuint fb)
-{
- MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
-
- GLuint readFB = ReadFB();
- mUserReadFB = fb;
- mInternalReadFB = (fb == 0) ? readFB : fb;
-
- mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
-
-#ifdef DEBUG
- mInInternalMode_ReadFB = false;
-#endif
-}
+ case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
+ mBoundDrawFB = fb;
+ break;
-void
-GLScreenBuffer::BindFB_Internal(GLuint fb)
-{
- mInternalDrawFB = mUserDrawFB = fb;
- mInternalReadFB = mUserReadFB = fb;
- mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
+ case LOCAL_GL_READ_FRAMEBUFFER_EXT:
+ mBoundReadFB = fb;
+ break;
-#ifdef DEBUG
- mInInternalMode_DrawFB = true;
- mInInternalMode_ReadFB = true;
-#endif
-}
-
-void
-GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
-{
- MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
-
- mInternalDrawFB = mUserDrawFB = fb;
- mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
-
-#ifdef DEBUG
- mInInternalMode_DrawFB = true;
-#endif
+ default:
+ break;
+ }
}
void
-GLScreenBuffer::BindReadFB_Internal(GLuint fb)
-{
- MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
-
- mInternalReadFB = mUserReadFB = fb;
- mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
-
-#ifdef DEBUG
- mInInternalMode_ReadFB = true;
-#endif
-}
-
-
-GLuint
-GLScreenBuffer::GetDrawFB() const
-{
-#ifdef DEBUG
- MOZ_ASSERT(mGL->IsCurrent());
- MOZ_ASSERT(!mInInternalMode_DrawFB);
-
- // Don't need a branch here, because:
- // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
- // We use raw_ here because this is debug code and we need to see what
- // the driver thinks.
- GLuint actual = 0;
- mGL->raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
-
- GLuint predicted = mInternalDrawFB;
- if (predicted != actual) {
- printf_stderr("Misprediction: Bound draw FB predicted: %d. Was: %d.\n",
- predicted, actual);
- MOZ_ASSERT(false, "Draw FB binding misprediction!");
- }
-#endif
-
- return mUserDrawFB;
-}
-
-GLuint
-GLScreenBuffer::GetReadFB() const
+GLScreenBuffer::OnDeleteFramebuffer(const GLuint fb)
{
-#ifdef DEBUG
- MOZ_ASSERT(mGL->IsCurrent());
- MOZ_ASSERT(!mInInternalMode_ReadFB);
-
- // We use raw_ here because this is debug code and we need to see what
- // the driver thinks.
- GLuint actual = 0;
- if (mGL->IsSupported(GLFeature::split_framebuffer))
- mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
- else
- mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
-
- GLuint predicted = mInternalReadFB;
- if (predicted != actual) {
- printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
- predicted, actual);
- MOZ_ASSERT(false, "Read FB binding misprediction!");
+ if (fb == mBoundDrawFB) {
+ mBoundDrawFB = 0;
}
-#endif
-
- return mUserReadFB;
-}
-
-GLuint
-GLScreenBuffer::GetFB() const
-{
- MOZ_ASSERT(GetDrawFB() == GetReadFB());
- return GetDrawFB();
-}
-
-
-void
-GLScreenBuffer::DeletingFB(GLuint fb)
-{
- if (fb == mInternalDrawFB) {
- mInternalDrawFB = 0;
- mUserDrawFB = 0;
- }
- if (fb == mInternalReadFB) {
- mInternalReadFB = 0;
- mUserReadFB = 0;
+ if (fb == mBoundReadFB) {
+ mBoundDrawFB = 0;
}
}
void
GLScreenBuffer::AfterDrawCall()
{
- if (mUserDrawFB != 0)
- return;
-
- RequireBlit();
+ if (mBoundDrawFB == DrawFB()) {
+ RequireBlit();
+ }
}
void
GLScreenBuffer::BeforeReadCall()
{
- if (mUserReadFB != 0)
- return;
-
- AssureBlitted();
+ if (mBoundReadFB == ReadFB()) {
+ AssureBlitted();
+ }
}
bool
GLScreenBuffer::CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border)
{
SharedSurface* surf;
- if (GetReadFB() == 0) {
+ if (mBoundReadFB == ReadFB()) {
surf = SharedSurf();
} else {
- surf = mGL->mFBOMapping[GetReadFB()];
+ surf = mGL->mFBOMapping[mBoundReadFB];
}
if (surf) {
return surf->CopyTexImage2D(target, level, internalformat, x, y, width, height, border);
}
return false;
}
@@ -412,20 +266,20 @@ GLScreenBuffer::ReadPixels(GLint x, GLin
GLvoid* pixels)
{
// If the currently bound framebuffer is backed by a SharedSurface
// then it might want to override how we read pixel data from it.
// This is normally only the default framebuffer, but we can also
// have SharedSurfaces bound to other framebuffers when doing
// readback for BasicLayers.
SharedSurface* surf;
- if (GetReadFB() == 0) {
+ if (mBoundReadFB == ReadFB()) {
surf = SharedSurf();
} else {
- surf = mGL->mFBOMapping[GetReadFB()];
+ surf = mGL->mFBOMapping[mBoundReadFB];
}
if (surf) {
return surf->ReadPixels(x, y, width, height, format, type, pixels);
}
return false;
}
@@ -437,29 +291,29 @@ GLScreenBuffer::RequireBlit()
void
GLScreenBuffer::AssureBlitted()
{
if (!mNeedsBlit)
return;
if (mDraw) {
- GLuint drawFB = DrawFB();
- GLuint readFB = ReadFB();
+ GLuint srcFB = DrawFB();
+ GLuint destFB = ReadFB();
- MOZ_ASSERT(drawFB != 0);
- MOZ_ASSERT(drawFB != readFB);
+ MOZ_ASSERT(srcFB != 0);
+ MOZ_ASSERT(srcFB != destFB);
MOZ_ASSERT(mGL->IsSupported(GLFeature::split_framebuffer));
MOZ_ASSERT(mDraw->mSize == mRead->Size());
ScopedBindFramebuffer boundFB(mGL);
ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
- BindReadFB_Internal(drawFB);
- BindDrawFB_Internal(readFB);
+ mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, srcFB);
+ mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, destFB);
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {
const gfx::IntSize& srcSize = mDraw->mSize;
const gfx::IntSize& destSize = mRead->Size();
mGL->raw_fBlitFramebuffer(0, 0, srcSize.width, srcSize.height,
0, 0, destSize.width, destSize.height,
LOCAL_GL_COLOR_BUFFER_BIT,
@@ -480,18 +334,16 @@ GLScreenBuffer::Morph(UniquePtr<SurfaceF
{
MOZ_RELEASE_ASSERT(newFactory, "newFactory must not be null");
mFactory = Move(newFactory);
}
bool
GLScreenBuffer::Attach(SharedSurface* surf, const gfx::IntSize& size)
{
- ScopedBindFramebuffer autoFB(mGL);
-
const bool readNeedsUnlock = (mRead && SharedSurf());
if (readNeedsUnlock) {
SharedSurf()->UnlockProd();
}
surf->LockProd();
if (mRead &&
@@ -531,25 +383,25 @@ GLScreenBuffer::Attach(SharedSurface* su
mDraw = Move(draw);
mRead = Move(read);
}
// Check that we're all set up.
MOZ_ASSERT(SharedSurf() == surf);
+ BindAsFramebuffer();
+
// Update the ReadBuffer mode.
if (mGL->IsSupported(gl::GLFeature::read_buffer)) {
- BindFB(0);
mRead->SetReadBuffer(mUserReadBufferMode);
}
// Update the DrawBuffer mode.
if (mGL->IsSupported(gl::GLFeature::draw_buffers)) {
- BindFB(0);
SetDrawBuffer(mUserDrawBufferMode);
}
RequireBlit();
return true;
}
@@ -661,30 +513,26 @@ GLScreenBuffer::CreateRead(SharedSurface
return ReadBuffer::Create(gl, caps, formats, surf);
}
void
GLScreenBuffer::SetDrawBuffer(GLenum mode)
{
MOZ_ASSERT(mGL->IsSupported(gl::GLFeature::draw_buffers));
- MOZ_ASSERT(GetDrawFB() == 0);
-
- if (!mGL->IsSupported(GLFeature::draw_buffers))
- return;
mUserDrawBufferMode = mode;
- GLuint fb = mDraw ? mDraw->mFB : mRead->mFB;
+ const auto drawFB = DrawFB();
GLenum internalMode;
switch (mode) {
case LOCAL_GL_BACK:
- internalMode = (fb == 0) ? LOCAL_GL_BACK
- : LOCAL_GL_COLOR_ATTACHMENT0;
+ internalMode = (drawFB == 0) ? LOCAL_GL_BACK
+ : LOCAL_GL_COLOR_ATTACHMENT0;
break;
case LOCAL_GL_NONE:
internalMode = LOCAL_GL_NONE;
break;
default:
MOZ_CRASH("GFX: Bad value.");
@@ -693,17 +541,16 @@ GLScreenBuffer::SetDrawBuffer(GLenum mod
mGL->MakeCurrent();
mGL->fDrawBuffers(1, &internalMode);
}
void
GLScreenBuffer::SetReadBuffer(GLenum mode)
{
MOZ_ASSERT(mGL->IsSupported(gl::GLFeature::read_buffer));
- MOZ_ASSERT(GetReadFB() == 0);
mUserReadBufferMode = mode;
mRead->SetReadBuffer(mUserReadBufferMode);
}
bool
GLScreenBuffer::IsDrawFramebufferDefault() const
{
--- a/gfx/gl/GLScreenBuffer.h
+++ b/gfx/gl/GLScreenBuffer.h
@@ -161,25 +161,18 @@ protected:
UniquePtr<ReadBuffer> mRead;
bool mNeedsBlit;
GLenum mUserReadBufferMode;
GLenum mUserDrawBufferMode;
// Below are the parts that help us pretend to be framebuffer 0:
- GLuint mUserDrawFB;
- GLuint mUserReadFB;
- GLuint mInternalDrawFB;
- GLuint mInternalReadFB;
-
-#ifdef DEBUG
- bool mInInternalMode_DrawFB;
- bool mInInternalMode_ReadFB;
-#endif
+ GLuint mBoundDrawFB;
+ GLuint mBoundReadFB;
GLScreenBuffer(GLContext* gl,
const SurfaceCaps& caps,
UniquePtr<SurfaceFactory> factory);
public:
virtual ~GLScreenBuffer();
@@ -223,17 +216,20 @@ public:
void DeletingFB(GLuint fb);
const gfx::IntSize& Size() const {
MOZ_ASSERT(mRead);
MOZ_ASSERT(!mDraw || mDraw->mSize == mRead->Size());
return mRead->Size();
}
- void BindAsFramebuffer(GLContext* const gl, GLenum target) const;
+ void BindAsFramebuffer(GLenum target = LOCAL_GL_FRAMEBUFFER) const;
+
+ void OnBindFramebuffer(GLenum target, GLuint fb);
+ void OnDeleteFramebuffer(GLuint fb);
void RequireBlit();
void AssureBlitted();
void AfterDrawCall();
void BeforeReadCall();
bool CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
GLint y, GLsizei width, GLsizei height, GLint border);
@@ -268,34 +264,16 @@ public:
protected:
bool Attach(SharedSurface* surf, const gfx::IntSize& size);
bool CreateDraw(const gfx::IntSize& size, UniquePtr<DrawBuffer>* out_buffer);
UniquePtr<ReadBuffer> CreateRead(SharedSurface* surf);
public:
- /* `fb` in these functions is the framebuffer the GLContext is hoping to
- * bind. When this is 0, we intercept the call and bind our own
- * framebuffers. As a client of these functions, just bind 0 when you want
- * to draw to the default framebuffer/'screen'.
- */
- void BindFB(GLuint fb);
- void BindDrawFB(GLuint fb);
- void BindReadFB(GLuint fb);
- GLuint GetFB() const;
- GLuint GetDrawFB() const;
- GLuint GetReadFB() const;
-
- // Here `fb` is the actual framebuffer you want bound. Binding 0 will
- // bind the (generally useless) default framebuffer.
- void BindFB_Internal(GLuint fb);
- void BindDrawFB_Internal(GLuint fb);
- void BindReadFB_Internal(GLuint fb);
-
bool IsDrawFramebufferDefault() const;
bool IsReadFramebufferDefault() const;
};
} // namespace gl
} // namespace mozilla
#endif // SCREEN_BUFFER_H_
--- a/gfx/gl/ScopedGLHelpers.cpp
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -58,44 +58,44 @@ ScopedGLState::UnwrapImpl()
/* ScopedBindFramebuffer - Saves and restores with GetUserBoundFB and BindUserFB. */
void
ScopedBindFramebuffer::Init()
{
if (mGL->IsSupported(GLFeature::split_framebuffer)) {
- mOldReadFB = mGL->GetReadFB();
- mOldDrawFB = mGL->GetDrawFB();
+ mOldReadFB = mGL->GetIntAs<GLuint>(LOCAL_GL_READ_FRAMEBUFFER_BINDING);
+ mOldDrawFB = mGL->GetIntAs<GLuint>(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING);
} else {
- mOldReadFB = mOldDrawFB = mGL->GetFB();
+ mOldReadFB = mOldDrawFB = mGL->GetIntAs<GLuint>(LOCAL_GL_FRAMEBUFFER_BINDING);
}
}
ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL)
: ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
{
Init();
}
ScopedBindFramebuffer::ScopedBindFramebuffer(GLContext* aGL, GLuint aNewFB)
: ScopedGLWrapper<ScopedBindFramebuffer>(aGL)
{
Init();
- mGL->BindFB(aNewFB);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aNewFB);
}
void
ScopedBindFramebuffer::UnwrapImpl()
{
if (mOldReadFB == mOldDrawFB) {
- mGL->BindFB(mOldDrawFB);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mOldDrawFB);
} else {
- mGL->BindDrawFB(mOldDrawFB);
- mGL->BindReadFB(mOldReadFB);
+ mGL->fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER, mOldDrawFB);
+ mGL->fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER, mOldReadFB);
}
}
/* ScopedBindTextureUnit ******************************************************/
ScopedBindTextureUnit::ScopedBindTextureUnit(GLContext* aGL, GLenum aTexUnit)
: ScopedGLWrapper<ScopedBindTextureUnit>(aGL)
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -63,27 +63,25 @@ SharedSurface::ProdCopy(SharedSurface* s
if (dest->mAttachType == AttachmentType::GLTexture) {
GLuint destTex = dest->ProdTexture();
GLenum destTarget = dest->ProdTextureTarget();
gl->BlitHelper()->BlitFramebufferToTexture(0, destTex,
src->mSize,
dest->mSize,
- destTarget,
- true);
+ destTarget);
} else if (dest->mAttachType == AttachmentType::GLRenderbuffer) {
GLuint destRB = dest->ProdRenderbuffer();
ScopedFramebufferForRenderbuffer destWrapper(gl, destRB);
gl->BlitHelper()->BlitFramebufferToFramebuffer(0,
destWrapper.FB(),
src->mSize,
- dest->mSize,
- true);
+ dest->mSize);
} else {
MOZ_CRASH("GFX: Unhandled dest->mAttachType 1.");
}
if (srcNeedsUnlock)
src->UnlockProd();
if (origNeedsRelock)
@@ -108,27 +106,25 @@ SharedSurface::ProdCopy(SharedSurface* s
if (src->mAttachType == AttachmentType::GLTexture) {
GLuint srcTex = src->ProdTexture();
GLenum srcTarget = src->ProdTextureTarget();
gl->BlitHelper()->BlitTextureToFramebuffer(srcTex, 0,
src->mSize,
dest->mSize,
- srcTarget,
- !!gl->Screen());
+ srcTarget);
} else if (src->mAttachType == AttachmentType::GLRenderbuffer) {
GLuint srcRB = src->ProdRenderbuffer();
ScopedFramebufferForRenderbuffer srcWrapper(gl, srcRB);
gl->BlitHelper()->BlitFramebufferToFramebuffer(srcWrapper.FB(),
0,
src->mSize,
- dest->mSize,
- true);
+ dest->mSize);
} else {
MOZ_CRASH("GFX: Unhandled src->mAttachType 2.");
}
if (destNeedsUnlock)
dest->UnlockProd();
if (origNeedsRelock)
@@ -444,20 +440,17 @@ ScopedReadbackFB::ScopedReadbackFB(Share
mSurfToLock = origLocked;
mSurfToLock->UnlockProd();
}
mSurfToUnlock = src;
mSurfToUnlock->LockProd();
}
- // TODO: This should just be BindFB, but we don't have
- // the patch for this yet. (bug 1045955)
- MOZ_ASSERT(mGL->Screen());
- mGL->Screen()->BindReadFB_Internal(0);
+ mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
break;
}
default:
MOZ_CRASH("GFX: Unhandled `mAttachType`.");
}
if (src->NeedsIndirectReads()) {
mGL->fGenTextures(1, &mTempTex);