gecko-dev/gfx/gl/GLScreenBuffer.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

928 строки
26 KiB
C++
Исходник Обычный вид История

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GLScreenBuffer.h"
#include <cstring>
#include "CompositorTypes.h"
Backed out 31 changesets (bug 1552643, bug 1550422) for xpcshell crash on a CLOSED TREE. Backed out changeset e30c1aa75529 (bug 1552643) Backed out changeset caadcd7e02d3 (bug 1552643) Backed out changeset aa7086ab09be (bug 1552643) Backed out changeset 0b4029671710 (bug 1550422) Backed out changeset a16295296035 (bug 1550422) Backed out changeset 3b70307c0db5 (bug 1550422) Backed out changeset 69df7818d4a3 (bug 1550422) Backed out changeset d98dfc565927 (bug 1550422) Backed out changeset 6f0997976944 (bug 1550422) Backed out changeset 0edd264464c2 (bug 1550422) Backed out changeset 9ea6da7a74ec (bug 1550422) Backed out changeset f855f9309c8b (bug 1550422) Backed out changeset 1033546224a7 (bug 1550422) Backed out changeset ade7384c6186 (bug 1550422) Backed out changeset 75b04de7e99c (bug 1550422) Backed out changeset 91c3acdb2454 (bug 1550422) Backed out changeset 77d2f80257d1 (bug 1550422) Backed out changeset e0cd10d35327 (bug 1550422) Backed out changeset 097091082423 (bug 1550422) Backed out changeset 2f328853c1ab (bug 1550422) Backed out changeset f92f2cc29cb1 (bug 1550422) Backed out changeset 6dc82f88333d (bug 1550422) Backed out changeset c20f66494d69 (bug 1550422) Backed out changeset 2ba22cddeb6f (bug 1550422) Backed out changeset 3aa72f89e295 (bug 1550422) Backed out changeset ab4c4e806977 (bug 1550422) Backed out changeset 72e5de040dda (bug 1550422) Backed out changeset 7d3c2d486706 (bug 1550422) Backed out changeset 132e0b8d8468 (bug 1550422) Backed out changeset 54c85ac75dd0 (bug 1550422) Backed out changeset d7ba4a18dd54 (bug 1550422)
2019-05-25 09:07:49 +03:00
#include "gfxPrefs.h"
#include "GLContext.h"
#include "GLBlitHelper.h"
#include "GLReadTexImageHelper.h"
#include "SharedSurfaceEGL.h"
#include "SharedSurfaceGL.h"
#include "ScopedGLHelpers.h"
#include "gfx2DGlue.h"
#include "../layers/ipc/ShadowLayers.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#ifdef XP_WIN
# include "SharedSurfaceANGLE.h" // for SurfaceFactory_ANGLEShareHandle
# include "SharedSurfaceD3D11Interop.h" // for SurfaceFactory_D3D11Interop
# include "mozilla/gfx/DeviceManagerDx.h"
#endif
#ifdef XP_MACOSX
# include "SharedSurfaceIO.h"
#endif
#ifdef MOZ_X11
# include "GLXLibrary.h"
# include "SharedSurfaceGLX.h"
#endif
namespace mozilla {
namespace gl {
using gfx::SurfaceFormat;
UniquePtr<GLScreenBuffer> GLScreenBuffer::Create(GLContext* gl,
const gfx::IntSize& size,
const SurfaceCaps& caps) {
UniquePtr<GLScreenBuffer> ret;
if (caps.antialias && !gl->IsSupported(GLFeature::framebuffer_multisample)) {
return ret;
}
layers::TextureFlags flags = layers::TextureFlags::ORIGIN_BOTTOM_LEFT;
if (!caps.premultAlpha) {
flags |= layers::TextureFlags::NON_PREMULTIPLIED;
}
UniquePtr<SurfaceFactory> factory =
MakeUnique<SurfaceFactory_Basic>(gl, caps, flags);
ret.reset(new GLScreenBuffer(gl, caps, std::move(factory)));
return ret;
}
/* static */
UniquePtr<SurfaceFactory> GLScreenBuffer::CreateFactory(
GLContext* gl, const SurfaceCaps& caps,
KnowsCompositor* compositorConnection, const layers::TextureFlags& flags) {
LayersIPCChannel* ipcChannel = compositorConnection->GetTextureForwarder();
const layers::LayersBackend backend =
compositorConnection->GetCompositorBackendType();
const bool useANGLE = compositorConnection->GetCompositorUseANGLE();
const bool useGl =
Backed out 31 changesets (bug 1552643, bug 1550422) for xpcshell crash on a CLOSED TREE. Backed out changeset e30c1aa75529 (bug 1552643) Backed out changeset caadcd7e02d3 (bug 1552643) Backed out changeset aa7086ab09be (bug 1552643) Backed out changeset 0b4029671710 (bug 1550422) Backed out changeset a16295296035 (bug 1550422) Backed out changeset 3b70307c0db5 (bug 1550422) Backed out changeset 69df7818d4a3 (bug 1550422) Backed out changeset d98dfc565927 (bug 1550422) Backed out changeset 6f0997976944 (bug 1550422) Backed out changeset 0edd264464c2 (bug 1550422) Backed out changeset 9ea6da7a74ec (bug 1550422) Backed out changeset f855f9309c8b (bug 1550422) Backed out changeset 1033546224a7 (bug 1550422) Backed out changeset ade7384c6186 (bug 1550422) Backed out changeset 75b04de7e99c (bug 1550422) Backed out changeset 91c3acdb2454 (bug 1550422) Backed out changeset 77d2f80257d1 (bug 1550422) Backed out changeset e0cd10d35327 (bug 1550422) Backed out changeset 097091082423 (bug 1550422) Backed out changeset 2f328853c1ab (bug 1550422) Backed out changeset f92f2cc29cb1 (bug 1550422) Backed out changeset 6dc82f88333d (bug 1550422) Backed out changeset c20f66494d69 (bug 1550422) Backed out changeset 2ba22cddeb6f (bug 1550422) Backed out changeset 3aa72f89e295 (bug 1550422) Backed out changeset ab4c4e806977 (bug 1550422) Backed out changeset 72e5de040dda (bug 1550422) Backed out changeset 7d3c2d486706 (bug 1550422) Backed out changeset 132e0b8d8468 (bug 1550422) Backed out changeset 54c85ac75dd0 (bug 1550422) Backed out changeset d7ba4a18dd54 (bug 1550422)
2019-05-25 09:07:49 +03:00
!gfxPrefs::WebGLForceLayersReadback() &&
(backend == layers::LayersBackend::LAYERS_OPENGL ||
(backend == layers::LayersBackend::LAYERS_WR && !useANGLE));
const bool useD3D =
Backed out 31 changesets (bug 1552643, bug 1550422) for xpcshell crash on a CLOSED TREE. Backed out changeset e30c1aa75529 (bug 1552643) Backed out changeset caadcd7e02d3 (bug 1552643) Backed out changeset aa7086ab09be (bug 1552643) Backed out changeset 0b4029671710 (bug 1550422) Backed out changeset a16295296035 (bug 1550422) Backed out changeset 3b70307c0db5 (bug 1550422) Backed out changeset 69df7818d4a3 (bug 1550422) Backed out changeset d98dfc565927 (bug 1550422) Backed out changeset 6f0997976944 (bug 1550422) Backed out changeset 0edd264464c2 (bug 1550422) Backed out changeset 9ea6da7a74ec (bug 1550422) Backed out changeset f855f9309c8b (bug 1550422) Backed out changeset 1033546224a7 (bug 1550422) Backed out changeset ade7384c6186 (bug 1550422) Backed out changeset 75b04de7e99c (bug 1550422) Backed out changeset 91c3acdb2454 (bug 1550422) Backed out changeset 77d2f80257d1 (bug 1550422) Backed out changeset e0cd10d35327 (bug 1550422) Backed out changeset 097091082423 (bug 1550422) Backed out changeset 2f328853c1ab (bug 1550422) Backed out changeset f92f2cc29cb1 (bug 1550422) Backed out changeset 6dc82f88333d (bug 1550422) Backed out changeset c20f66494d69 (bug 1550422) Backed out changeset 2ba22cddeb6f (bug 1550422) Backed out changeset 3aa72f89e295 (bug 1550422) Backed out changeset ab4c4e806977 (bug 1550422) Backed out changeset 72e5de040dda (bug 1550422) Backed out changeset 7d3c2d486706 (bug 1550422) Backed out changeset 132e0b8d8468 (bug 1550422) Backed out changeset 54c85ac75dd0 (bug 1550422) Backed out changeset d7ba4a18dd54 (bug 1550422)
2019-05-25 09:07:49 +03:00
!gfxPrefs::WebGLForceLayersReadback() &&
(backend == layers::LayersBackend::LAYERS_D3D11 ||
(backend == layers::LayersBackend::LAYERS_WR && useANGLE));
UniquePtr<SurfaceFactory> factory = nullptr;
if (useGl) {
#if defined(XP_MACOSX)
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
#elif defined(MOZ_X11)
if (sGLXLibrary.UseTextureFromPixmap())
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
#elif defined(MOZ_WIDGET_UIKIT)
factory = MakeUnique<SurfaceFactory_GLTexture>(mGLContext, caps, ipcChannel,
mFlags);
#elif defined(MOZ_WIDGET_ANDROID)
if (XRE_IsParentProcess() && !StaticPrefs::WebGLSurfaceTextureEnabled()) {
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
} else {
factory =
SurfaceFactory_SurfaceTexture::Create(gl, caps, ipcChannel, flags);
}
#else
if (gl->GetContextType() == GLContextType::EGL) {
if (XRE_IsParentProcess()) {
factory = SurfaceFactory_EGLImage::Create(gl, caps, ipcChannel, flags);
}
}
#endif
} else if (useD3D) {
#ifdef XP_WIN
// Ensure devices initialization. SharedSurfaceANGLE and
// SharedSurfaceD3D11Interop use them. The devices are lazily initialized
// with WebRender to reduce memory usage.
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
// Enable surface sharing only if ANGLE and compositing devices
// are both WARP or both not WARP
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();
if (gl->IsANGLE() && (gl->IsWARP() == dm->IsWARP()) &&
dm->TextureSharingWorks()) {
factory =
SurfaceFactory_ANGLEShareHandle::Create(gl, caps, ipcChannel, flags);
}
if (!factory && StaticPrefs::WebGLDXGLEnabled()) {
factory =
SurfaceFactory_D3D11Interop::Create(gl, caps, ipcChannel, flags);
}
#endif
}
#ifdef MOZ_X11
if (!factory && sGLXLibrary.UseTextureFromPixmap()) {
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);
}
#endif
return factory;
}
GLScreenBuffer::GLScreenBuffer(GLContext* gl, const SurfaceCaps& caps,
UniquePtr<SurfaceFactory> factory)
: mGL(gl),
mCaps(caps),
mFactory(std::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
{
}
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 {
GLuint drawFB = DrawFB();
GLuint readFB = ReadFB();
if (!gl->IsSupported(GLFeature::split_framebuffer)) {
MOZ_ASSERT(drawFB == readFB);
gl->raw_fBindFramebuffer(target, readFB);
return;
}
switch (target) {
case LOCAL_GL_FRAMEBUFFER:
gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
break;
case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
break;
case LOCAL_GL_READ_FRAMEBUFFER_EXT:
gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
break;
default:
MOZ_CRASH("GFX: Bad `target` for BindFramebuffer.");
}
}
void GLScreenBuffer::BindFB(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
}
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
}
void GLScreenBuffer::BindFB_Internal(GLuint fb) {
mInternalDrawFB = mUserDrawFB = fb;
mInternalReadFB = mUserReadFB = fb;
mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
#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
}
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(!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 && !mGL->CheckContextLost()) {
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 {
#ifdef DEBUG
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 && !mGL->CheckContextLost()) {
printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
predicted, actual);
MOZ_ASSERT(false, "Read FB binding misprediction!");
}
#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;
}
}
void GLScreenBuffer::AfterDrawCall() {
if (mUserDrawFB != 0) return;
RequireBlit();
}
void GLScreenBuffer::BeforeReadCall() {
if (mUserReadFB != 0) return;
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) {
surf = SharedSurf();
} else {
surf = mGL->mFBOMapping[GetReadFB()];
}
if (surf) {
return surf->CopyTexImage2D(target, level, internalformat, x, y, width,
height, border);
}
return false;
}
bool GLScreenBuffer::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type, 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) {
surf = SharedSurf();
} else {
surf = mGL->mFBOMapping[GetReadFB()];
}
if (surf) {
return surf->ReadPixels(x, y, width, height, format, type, pixels);
}
return false;
}
void GLScreenBuffer::RequireBlit() { mNeedsBlit = true; }
void GLScreenBuffer::AssureBlitted() {
if (!mNeedsBlit) return;
if (mDraw) {
GLuint drawFB = DrawFB();
GLuint readFB = ReadFB();
MOZ_ASSERT(drawFB != 0);
MOZ_ASSERT(drawFB != readFB);
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);
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, LOCAL_GL_NEAREST);
} else if (mGL->IsExtensionSupported(
GLContext::APPLE_framebuffer_multisample)) {
mGL->fResolveMultisampleFramebufferAPPLE();
} else {
MOZ_CRASH("GFX: No available blit methods.");
}
// Done!
}
mNeedsBlit = false;
}
void GLScreenBuffer::Morph(UniquePtr<SurfaceFactory> newFactory) {
MOZ_RELEASE_ASSERT(newFactory, "newFactory must not be null");
mFactory = std::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 && surf->mAttachType == SharedSurf()->mAttachType &&
size == Size()) {
// Same size, same type, ready for reuse!
mRead->Attach(surf);
} else {
// Else something changed, so resize:
UniquePtr<DrawBuffer> draw;
bool drawOk = true;
/* Don't change out the draw buffer unless we resize. In the
* preserveDrawingBuffer:true case, prior contents of the buffer must
* be retained. If we're using a draw buffer, it's an MSAA buffer, so
* even if we copy the previous frame into the (single-sampled) read
* buffer, if we need to re-resolve from draw to read (as triggered by
* drawing), we'll need the old MSAA content to still be in the draw
* buffer.
*/
if (!mDraw || size != Size())
drawOk = CreateDraw(size, &draw); // Can be null.
UniquePtr<ReadBuffer> read = CreateRead(surf);
bool readOk = !!read;
if (!drawOk || !readOk) {
surf->UnlockProd();
if (readNeedsUnlock) {
SharedSurf()->LockProd();
}
return false;
}
if (draw) mDraw = std::move(draw);
mRead = std::move(read);
}
// Check that we're all set up.
MOZ_ASSERT(SharedSurf() == surf);
// 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;
}
bool GLScreenBuffer::Swap(const gfx::IntSize& size) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
if (!newBack) return false;
// In the case of DXGL interop, the new surface needs to be acquired before
// it is attached so that the interop surface is locked, which populates
// the GL renderbuffer. This results in the renderbuffer being ready and
// attachment to framebuffer succeeds in Attach() call.
newBack->Surf()->ProducerAcquire();
if (!Attach(newBack->Surf(), size)) {
newBack->Surf()->ProducerRelease();
return false;
}
// Attach was successful.
mFront = mBack;
mBack = newBack;
if (ShouldPreserveBuffer() && mFront && mBack && !mDraw) {
auto src = mFront->Surf();
auto dest = mBack->Surf();
// uint32_t srcPixel = ReadPixel(src);
// uint32_t destPixel = ReadPixel(dest);
// printf_stderr("Before: src: 0x%08x, dest: 0x%08x\n", srcPixel,
// destPixel);
#ifdef DEBUG
GLContext::LocalErrorScope errorScope(*mGL);
#endif
SharedSurface::ProdCopy(src, dest, mFactory.get());
#ifdef DEBUG
MOZ_ASSERT(!errorScope.GetError());
#endif
// srcPixel = ReadPixel(src);
// destPixel = ReadPixel(dest);
// printf_stderr("After: src: 0x%08x, dest: 0x%08x\n", srcPixel, destPixel);
}
// XXX: We would prefer to fence earlier on platforms that don't need
// the full ProducerAcquire/ProducerRelease semantics, so that the fence
// doesn't include the copy operation. Unfortunately, the current API
// doesn't expose a good way to do that.
if (mFront) {
mFront->Surf()->ProducerRelease();
}
return true;
}
bool GLScreenBuffer::PublishFrame(const gfx::IntSize& size) {
AssureBlitted();
bool good = Swap(size);
return good;
}
bool GLScreenBuffer::Resize(const gfx::IntSize& size) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<SharedSurfaceTextureClient> newBack = mFactory->NewTexClient(size);
if (!newBack) return false;
if (!Attach(newBack->Surf(), size)) return false;
if (mBack) mBack->Surf()->ProducerRelease();
mBack = newBack;
mBack->Surf()->ProducerAcquire();
return true;
}
bool GLScreenBuffer::CreateDraw(const gfx::IntSize& size,
UniquePtr<DrawBuffer>* out_buffer) {
GLContext* gl = mFactory->mGL;
const GLFormats& formats = mFactory->mFormats;
const SurfaceCaps& caps = mFactory->DrawCaps();
return DrawBuffer::Create(gl, caps, formats, size, out_buffer);
}
UniquePtr<ReadBuffer> GLScreenBuffer::CreateRead(SharedSurface* surf) {
GLContext* gl = mFactory->mGL;
const GLFormats& formats = mFactory->mFormats;
const SurfaceCaps& caps = mFactory->ReadCaps();
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;
GLenum internalMode;
switch (mode) {
case LOCAL_GL_BACK:
internalMode = (fb == 0) ? LOCAL_GL_BACK : LOCAL_GL_COLOR_ATTACHMENT0;
break;
case LOCAL_GL_NONE:
internalMode = LOCAL_GL_NONE;
break;
default:
MOZ_CRASH("GFX: Bad value.");
}
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 {
if (!mDraw) return IsReadFramebufferDefault();
return mDraw->mFB == 0;
}
bool GLScreenBuffer::IsReadFramebufferDefault() const {
return SharedSurf()->mAttachType == AttachmentType::Screen;
}
uint32_t GLScreenBuffer::DepthBits() const {
const GLFormats& formats = mFactory->mFormats;
if (formats.depth == LOCAL_GL_DEPTH_COMPONENT16) return 16;
return 24;
}
////////////////////////////////////////////////////////////////////////
// Utils
static void RenderbufferStorageBySamples(GLContext* aGL, GLsizei aSamples,
GLenum aInternalFormat,
const gfx::IntSize& aSize) {
if (aSamples) {
aGL->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER, aSamples,
aInternalFormat, aSize.width,
aSize.height);
} else {
aGL->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, aInternalFormat,
aSize.width, aSize.height);
}
}
static GLuint CreateRenderbuffer(GLContext* aGL, GLenum aFormat,
GLsizei aSamples, const gfx::IntSize& aSize) {
GLuint rb = 0;
aGL->fGenRenderbuffers(1, &rb);
ScopedBindRenderbuffer autoRB(aGL, rb);
RenderbufferStorageBySamples(aGL, aSamples, aFormat, aSize);
return rb;
}
static void CreateRenderbuffersForOffscreen(
GLContext* aGL, const GLFormats& aFormats, const gfx::IntSize& aSize,
bool aMultisample, GLuint* aColorMSRB, GLuint* aDepthRB,
GLuint* aStencilRB) {
GLsizei samples = aMultisample ? aFormats.samples : 0;
if (aColorMSRB) {
MOZ_ASSERT(aFormats.samples > 0);
MOZ_ASSERT(aFormats.color_rbFormat);
GLenum colorFormat = aFormats.color_rbFormat;
if (aGL->IsANGLE()) {
MOZ_ASSERT(colorFormat == LOCAL_GL_RGBA8);
colorFormat = LOCAL_GL_BGRA8_EXT;
}
*aColorMSRB = CreateRenderbuffer(aGL, colorFormat, samples, aSize);
}
if (aDepthRB && aStencilRB && aFormats.depthStencil) {
*aDepthRB = CreateRenderbuffer(aGL, aFormats.depthStencil, samples, aSize);
*aStencilRB = *aDepthRB;
} else {
if (aDepthRB) {
MOZ_ASSERT(aFormats.depth);
*aDepthRB = CreateRenderbuffer(aGL, aFormats.depth, samples, aSize);
}
if (aStencilRB) {
MOZ_ASSERT(aFormats.stencil);
*aStencilRB = CreateRenderbuffer(aGL, aFormats.stencil, samples, aSize);
}
}
}
////////////////////////////////////////////////////////////////////////
// DrawBuffer
bool DrawBuffer::Create(GLContext* const gl, const SurfaceCaps& caps,
const GLFormats& formats, const gfx::IntSize& size,
UniquePtr<DrawBuffer>* out_buffer) {
MOZ_ASSERT(out_buffer);
*out_buffer = nullptr;
if (!caps.color) {
MOZ_ASSERT(!caps.alpha && !caps.depth && !caps.stencil);
// Nothing is needed.
return true;
}
if (caps.antialias) {
if (formats.samples == 0) return false; // Can't create it.
MOZ_ASSERT(uint32_t(formats.samples) <= gl->MaxSamples());
}
GLuint colorMSRB = 0;
GLuint depthRB = 0;
GLuint stencilRB = 0;
GLuint* pColorMSRB = caps.antialias ? &colorMSRB : nullptr;
GLuint* pDepthRB = caps.depth ? &depthRB : nullptr;
GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
if (!formats.color_rbFormat) pColorMSRB = nullptr;
if (pDepthRB && pStencilRB) {
if (!formats.depth && !formats.depthStencil) pDepthRB = nullptr;
if (!formats.stencil && !formats.depthStencil) pStencilRB = nullptr;
} else {
if (!formats.depth) pDepthRB = nullptr;
if (!formats.stencil) pStencilRB = nullptr;
}
GLContext::LocalErrorScope localError(*gl);
CreateRenderbuffersForOffscreen(gl, formats, size, caps.antialias, pColorMSRB,
pDepthRB, pStencilRB);
GLuint fb = 0;
gl->fGenFramebuffers(1, &fb);
gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
const GLsizei samples = formats.samples;
UniquePtr<DrawBuffer> ret(
new DrawBuffer(gl, size, samples, fb, colorMSRB, depthRB, stencilRB));
GLenum err = localError.GetError();
MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
if (err || !gl->IsFramebufferComplete(fb)) return false;
*out_buffer = std::move(ret);
return true;
}
DrawBuffer::~DrawBuffer() {
if (!mGL->MakeCurrent()) return;
GLuint fb = mFB;
GLuint rbs[] = {
mColorMSRB, mDepthRB,
(mStencilRB != mDepthRB) ? mStencilRB
: 0, // Don't double-delete DEPTH_STENCIL RBs.
};
mGL->fDeleteFramebuffers(1, &fb);
mGL->fDeleteRenderbuffers(3, rbs);
}
////////////////////////////////////////////////////////////////////////
// ReadBuffer
UniquePtr<ReadBuffer> ReadBuffer::Create(GLContext* gl, const SurfaceCaps& caps,
const GLFormats& formats,
SharedSurface* surf) {
MOZ_ASSERT(surf);
if (surf->mAttachType == AttachmentType::Screen) {
// Don't need anything. Our read buffer will be the 'screen'.
return UniquePtr<ReadBuffer>(new ReadBuffer(gl, 0, 0, 0, surf));
}
GLuint depthRB = 0;
GLuint stencilRB = 0;
GLuint* pDepthRB = caps.depth ? &depthRB : nullptr;
GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
GLContext::LocalErrorScope localError(*gl);
CreateRenderbuffersForOffscreen(gl, formats, surf->mSize, caps.antialias,
nullptr, pDepthRB, pStencilRB);
GLuint colorTex = 0;
GLuint colorRB = 0;
GLenum target = 0;
switch (surf->mAttachType) {
case AttachmentType::GLTexture:
colorTex = surf->ProdTexture();
target = surf->ProdTextureTarget();
break;
case AttachmentType::GLRenderbuffer:
colorRB = surf->ProdRenderbuffer();
break;
default:
MOZ_CRASH("GFX: Unknown attachment type, create?");
}
MOZ_ASSERT(colorTex || colorRB);
GLuint fb = 0;
gl->fGenFramebuffers(1, &fb);
gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb, target);
gl->mFBOMapping[fb] = surf;
UniquePtr<ReadBuffer> ret(new ReadBuffer(gl, fb, depthRB, stencilRB, surf));
GLenum err = localError.GetError();
MOZ_ASSERT_IF(err != LOCAL_GL_NO_ERROR, err == LOCAL_GL_OUT_OF_MEMORY);
if (err) return nullptr;
const bool needsAcquire = !surf->IsProducerAcquired();
if (needsAcquire) {
surf->ProducerReadAcquire();
}
const bool isComplete = gl->IsFramebufferComplete(fb);
if (needsAcquire) {
surf->ProducerReadRelease();
}
if (!isComplete) return nullptr;
return ret;
}
ReadBuffer::~ReadBuffer() {
if (!mGL->MakeCurrent()) return;
GLuint fb = mFB;
GLuint rbs[] = {
mDepthRB,
(mStencilRB != mDepthRB) ? mStencilRB
: 0, // Don't double-delete DEPTH_STENCIL RBs.
};
mGL->fDeleteFramebuffers(1, &fb);
mGL->fDeleteRenderbuffers(2, rbs);
mGL->mFBOMapping.erase(mFB);
}
void ReadBuffer::Attach(SharedSurface* surf) {
MOZ_ASSERT(surf && mSurf);
MOZ_ASSERT(surf->mAttachType == mSurf->mAttachType);
MOZ_ASSERT(surf->mSize == mSurf->mSize);
// Nothing else is needed for AttachType Screen.
if (surf->mAttachType != AttachmentType::Screen) {
GLuint colorTex = 0;
GLuint colorRB = 0;
GLenum target = 0;
switch (surf->mAttachType) {
case AttachmentType::GLTexture:
colorTex = surf->ProdTexture();
target = surf->ProdTextureTarget();
break;
case AttachmentType::GLRenderbuffer:
colorRB = surf->ProdRenderbuffer();
break;
default:
MOZ_CRASH("GFX: Unknown attachment type, attach?");
}
mGL->AttachBuffersToFB(colorTex, colorRB, 0, 0, mFB, target);
mGL->mFBOMapping[mFB] = surf;
MOZ_GL_ASSERT(mGL, mGL->IsFramebufferComplete(mFB));
}
mSurf = surf;
}
const gfx::IntSize& ReadBuffer::Size() const { return mSurf->mSize; }
void ReadBuffer::SetReadBuffer(GLenum userMode) const {
if (!mGL->IsSupported(GLFeature::read_buffer)) return;
GLenum internalMode;
switch (userMode) {
case LOCAL_GL_BACK:
case LOCAL_GL_FRONT:
internalMode = (mFB == 0) ? userMode : LOCAL_GL_COLOR_ATTACHMENT0;
break;
case LOCAL_GL_NONE:
internalMode = LOCAL_GL_NONE;
break;
default:
MOZ_CRASH("GFX: Bad value.");
}
mGL->MakeCurrent();
mGL->fReadBuffer(internalMode);
}
} /* namespace gl */
} /* namespace mozilla */