1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/client/ClientCanvasLayer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,181 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "ClientCanvasLayer.h" 1.10 +#include "GLContext.h" // for GLContext 1.11 +#include "GLScreenBuffer.h" // for GLScreenBuffer 1.12 +#include "GeckoProfiler.h" // for PROFILER_LABEL 1.13 +#include "SharedSurfaceEGL.h" // for SurfaceFactory_EGLImage 1.14 +#include "SharedSurfaceGL.h" // for SurfaceFactory_GLTexture, etc 1.15 +#include "SurfaceStream.h" // for SurfaceStream, etc 1.16 +#include "SurfaceTypes.h" // for SurfaceStreamType 1.17 +#include "ClientLayerManager.h" // for ClientLayerManager, etc 1.18 +#include "mozilla/gfx/Point.h" // for IntSize 1.19 +#include "mozilla/layers/CompositorTypes.h" 1.20 +#include "mozilla/layers/LayersTypes.h" 1.21 +#include "nsCOMPtr.h" // for already_AddRefed 1.22 +#include "nsISupportsImpl.h" // for Layer::AddRef, etc 1.23 +#include "nsRect.h" // for nsIntRect 1.24 +#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc 1.25 +#ifdef MOZ_WIDGET_GONK 1.26 +#include "SharedSurfaceGralloc.h" 1.27 +#endif 1.28 +#ifdef XP_MACOSX 1.29 +#include "SharedSurfaceIO.h" 1.30 +#endif 1.31 +#include "gfxPrefs.h" // for WebGLForceLayersReadback 1.32 + 1.33 +using namespace mozilla::gfx; 1.34 +using namespace mozilla::gl; 1.35 + 1.36 +namespace mozilla { 1.37 +namespace layers { 1.38 + 1.39 +ClientCanvasLayer::~ClientCanvasLayer() 1.40 +{ 1.41 + MOZ_COUNT_DTOR(ClientCanvasLayer); 1.42 + if (mCanvasClient) { 1.43 + mCanvasClient->OnDetach(); 1.44 + mCanvasClient = nullptr; 1.45 + } 1.46 + if (mTextureSurface) { 1.47 + delete mTextureSurface; 1.48 + } 1.49 +} 1.50 + 1.51 +void 1.52 +ClientCanvasLayer::Initialize(const Data& aData) 1.53 +{ 1.54 + CopyableCanvasLayer::Initialize(aData); 1.55 + 1.56 + mCanvasClient = nullptr; 1.57 + 1.58 + if (mGLContext) { 1.59 + GLScreenBuffer* screen = mGLContext->Screen(); 1.60 + 1.61 + SurfaceCaps caps = screen->Caps(); 1.62 + if (mStream) { 1.63 + // The screen caps are irrelevant if we're using a separate stream 1.64 + caps = GetContentFlags() & CONTENT_OPAQUE ? SurfaceCaps::ForRGB() : SurfaceCaps::ForRGBA(); 1.65 + } 1.66 + 1.67 + SurfaceStreamType streamType = 1.68 + SurfaceStream::ChooseGLStreamType(SurfaceStream::OffMainThread, 1.69 + screen->PreserveBuffer()); 1.70 + SurfaceFactory_GL* factory = nullptr; 1.71 + if (!gfxPrefs::WebGLForceLayersReadback()) { 1.72 + if (ClientManager()->AsShadowForwarder()->GetCompositorBackendType() == mozilla::layers::LayersBackend::LAYERS_OPENGL) { 1.73 + if (mGLContext->GetContextType() == GLContextType::EGL) { 1.74 + bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); 1.75 + 1.76 + if (!isCrossProcess) { 1.77 + // [Basic/OGL Layers, OMTC] WebGL layer init. 1.78 + factory = SurfaceFactory_EGLImage::Create(mGLContext, caps); 1.79 + } else { 1.80 + // [Basic/OGL Layers, OOPC] WebGL layer init. (Out Of Process Compositing) 1.81 +#ifdef MOZ_WIDGET_GONK 1.82 + factory = new SurfaceFactory_Gralloc(mGLContext, caps, ClientManager()->AsShadowForwarder()); 1.83 +#else 1.84 + // we could do readback here maybe 1.85 + NS_NOTREACHED("isCrossProcess but not on native B2G!"); 1.86 +#endif 1.87 + } 1.88 + } else { 1.89 + // [Basic Layers, OMTC] WebGL layer init. 1.90 + // Well, this *should* work... 1.91 +#ifdef XP_MACOSX 1.92 + factory = new SurfaceFactory_IOSurface(mGLContext, caps); 1.93 +#else 1.94 + factory = new SurfaceFactory_GLTexture(mGLContext, nullptr, caps); 1.95 +#endif 1.96 + } 1.97 + } 1.98 + } 1.99 + 1.100 + if (mStream) { 1.101 + // We're using a stream other than the one in the default screen 1.102 + mFactory = factory; 1.103 + if (!mFactory) { 1.104 + // Absolutely must have a factory here, so create a basic one 1.105 + mFactory = new SurfaceFactory_Basic(mGLContext, caps); 1.106 + } 1.107 + 1.108 + gfx::IntSize size = gfx::IntSize(aData.mSize.width, aData.mSize.height); 1.109 + mTextureSurface = SharedSurface_GLTexture::Create(mGLContext, mGLContext, 1.110 + mGLContext->GetGLFormats(), 1.111 + size, caps.alpha, aData.mTexID); 1.112 + SharedSurface* producer = mStream->SwapProducer(mFactory, size); 1.113 + if (!producer) { 1.114 + // Fallback to basic factory 1.115 + delete mFactory; 1.116 + mFactory = new SurfaceFactory_Basic(mGLContext, caps); 1.117 + producer = mStream->SwapProducer(mFactory, size); 1.118 + MOZ_ASSERT(producer, "Failed to create initial canvas surface with basic factory"); 1.119 + } 1.120 + } else if (factory) { 1.121 + screen->Morph(factory, streamType); 1.122 + } 1.123 + } 1.124 +} 1.125 + 1.126 +void 1.127 +ClientCanvasLayer::RenderLayer() 1.128 +{ 1.129 + PROFILER_LABEL("ClientCanvasLayer", "Paint"); 1.130 + if (!IsDirty()) { 1.131 + return; 1.132 + } 1.133 + 1.134 + if (GetMaskLayer()) { 1.135 + ToClientLayer(GetMaskLayer())->RenderLayer(); 1.136 + } 1.137 + 1.138 + if (!mCanvasClient) { 1.139 + TextureFlags flags = TEXTURE_IMMEDIATE_UPLOAD; 1.140 + if (mNeedsYFlip) { 1.141 + flags |= TEXTURE_NEEDS_Y_FLIP; 1.142 + } 1.143 + 1.144 + if (!mGLContext) { 1.145 + // We don't support locking for buffer surfaces currently 1.146 + flags |= TEXTURE_IMMEDIATE_UPLOAD; 1.147 + } else { 1.148 + // GLContext's SurfaceStream handles ownership itself, 1.149 + // and doesn't require layers to do any deallocation. 1.150 + flags |= TEXTURE_DEALLOCATE_CLIENT; 1.151 + } 1.152 + mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(), 1.153 + ClientManager()->AsShadowForwarder(), flags); 1.154 + if (!mCanvasClient) { 1.155 + return; 1.156 + } 1.157 + if (HasShadow()) { 1.158 + mCanvasClient->Connect(); 1.159 + ClientManager()->AsShadowForwarder()->Attach(mCanvasClient, this); 1.160 + } 1.161 + } 1.162 + 1.163 + FirePreTransactionCallback(); 1.164 + mCanvasClient->Update(gfx::IntSize(mBounds.width, mBounds.height), this); 1.165 + 1.166 + FireDidTransactionCallback(); 1.167 + 1.168 + ClientManager()->Hold(this); 1.169 + mCanvasClient->Updated(); 1.170 + mCanvasClient->OnTransaction(); 1.171 +} 1.172 + 1.173 +already_AddRefed<CanvasLayer> 1.174 +ClientLayerManager::CreateCanvasLayer() 1.175 +{ 1.176 + NS_ASSERTION(InConstruction(), "Only allowed in construction phase"); 1.177 + nsRefPtr<ClientCanvasLayer> layer = 1.178 + new ClientCanvasLayer(this); 1.179 + CREATE_SHADOW(Canvas); 1.180 + return layer.forget(); 1.181 +} 1.182 + 1.183 +} 1.184 +}