michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "CompositingRenderTargetOGL.h" michael@0: #include "GLContext.h" michael@0: #include "GLReadTexImageHelper.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: michael@0: using namespace mozilla; michael@0: using namespace mozilla::gfx; michael@0: using namespace mozilla::gl; michael@0: using namespace mozilla::layers; michael@0: michael@0: CompositingRenderTargetOGL::~CompositingRenderTargetOGL() michael@0: { michael@0: mGL->fDeleteTextures(1, &mTextureHandle); michael@0: mGL->fDeleteFramebuffers(1, &mFBO); michael@0: } michael@0: michael@0: void michael@0: CompositingRenderTargetOGL::BindTexture(GLenum aTextureUnit, GLenum aTextureTarget) michael@0: { michael@0: MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); michael@0: MOZ_ASSERT(mTextureHandle != 0); michael@0: mGL->fActiveTexture(aTextureUnit); michael@0: mGL->fBindTexture(aTextureTarget, mTextureHandle); michael@0: } michael@0: michael@0: void michael@0: CompositingRenderTargetOGL::BindRenderTarget() michael@0: { michael@0: if (mInitParams.mStatus != InitParams::INITIALIZED) { michael@0: InitializeImpl(); michael@0: } else { michael@0: MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); michael@0: mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); michael@0: GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); michael@0: if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { michael@0: // The main framebuffer (0) of non-offscreen contexts michael@0: // might be backed by a EGLSurface that needs to be renewed. michael@0: if (mFBO == 0 && !mGL->IsOffscreen()) { michael@0: mGL->RenewSurface(); michael@0: result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); michael@0: } michael@0: if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { michael@0: nsAutoCString msg; michael@0: msg.AppendPrintf("Framebuffer not complete -- CheckFramebufferStatus returned 0x%x, " michael@0: "GLContext=%p, IsOffscreen()=%d, mFBO=%d, aFBOTextureTarget=0x%x, " michael@0: "aRect.width=%d, aRect.height=%d", michael@0: result, mGL, mGL->IsOffscreen(), mFBO, mInitParams.mFBOTextureTarget, michael@0: mInitParams.mSize.width, mInitParams.mSize.height); michael@0: NS_WARNING(msg.get()); michael@0: } michael@0: } michael@0: michael@0: mCompositor->PrepareViewport(mInitParams.mSize, mTransform); michael@0: } michael@0: } michael@0: michael@0: #ifdef MOZ_DUMP_PAINTING michael@0: TemporaryRef michael@0: CompositingRenderTargetOGL::Dump(Compositor* aCompositor) michael@0: { michael@0: MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED); michael@0: CompositorOGL* compositorOGL = static_cast(aCompositor); michael@0: return ReadBackSurface(mGL, mTextureHandle, true, compositorOGL->GetFBOFormat()); michael@0: } michael@0: #endif michael@0: michael@0: void michael@0: CompositingRenderTargetOGL::InitializeImpl() michael@0: { michael@0: MOZ_ASSERT(mInitParams.mStatus == InitParams::READY); michael@0: michael@0: mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mFBO); michael@0: mGL->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, michael@0: LOCAL_GL_COLOR_ATTACHMENT0, michael@0: mInitParams.mFBOTextureTarget, michael@0: mTextureHandle, michael@0: 0); michael@0: michael@0: // Making this call to fCheckFramebufferStatus prevents a crash on michael@0: // PowerVR. See bug 695246. michael@0: GLenum result = mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER); michael@0: if (result != LOCAL_GL_FRAMEBUFFER_COMPLETE) { michael@0: nsAutoCString msg; michael@0: msg.AppendPrintf("Framebuffer not complete -- error 0x%x, aFBOTextureTarget 0x%x, mFBO %d, mTextureHandle %d, aRect.width %d, aRect.height %d", michael@0: result, mInitParams.mFBOTextureTarget, mFBO, mTextureHandle, mInitParams.mSize.width, mInitParams.mSize.height); michael@0: NS_ERROR(msg.get()); michael@0: } michael@0: michael@0: mCompositor->PrepareViewport(mInitParams.mSize, mTransform); michael@0: mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height); michael@0: if (mInitParams.mInit == INIT_MODE_CLEAR) { michael@0: mGL->fClearColor(0.0, 0.0, 0.0, 0.0); michael@0: mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); michael@0: } michael@0: michael@0: mInitParams.mStatus = InitParams::INITIALIZED; michael@0: }