1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/layers/client/CanvasClient.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,190 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; 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 "mozilla/layers/CanvasClient.h" 1.10 +#include "ClientCanvasLayer.h" // for ClientCanvasLayer 1.11 +#include "GLContext.h" // for GLContext 1.12 +#include "GLScreenBuffer.h" // for GLScreenBuffer 1.13 +#include "SurfaceStream.h" // for SurfaceStream 1.14 +#include "SurfaceTypes.h" // for SurfaceStreamHandle 1.15 +#include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat 1.16 +#include "gfxPlatform.h" // for gfxPlatform 1.17 +#include "mozilla/gfx/BaseSize.h" // for BaseSize 1.18 +#include "mozilla/layers/CompositableForwarder.h" 1.19 +#include "mozilla/layers/GrallocTextureClient.h" 1.20 +#include "mozilla/layers/LayersTypes.h" 1.21 +#include "mozilla/layers/TextureClient.h" // for TextureClient, etc 1.22 +#include "mozilla/layers/TextureClientOGL.h" 1.23 +#include "nsAutoPtr.h" // for nsRefPtr 1.24 +#include "nsDebug.h" // for printf_stderr, NS_ASSERTION 1.25 +#include "nsXULAppAPI.h" // for XRE_GetProcessType, etc 1.26 +#ifdef MOZ_WIDGET_GONK 1.27 +#include "SharedSurfaceGralloc.h" 1.28 +#endif 1.29 + 1.30 +using namespace mozilla::gfx; 1.31 +using namespace mozilla::gl; 1.32 + 1.33 +namespace mozilla { 1.34 +namespace layers { 1.35 + 1.36 +/* static */ TemporaryRef<CanvasClient> 1.37 +CanvasClient::CreateCanvasClient(CanvasClientType aType, 1.38 + CompositableForwarder* aForwarder, 1.39 + TextureFlags aFlags) 1.40 +{ 1.41 +#ifndef MOZ_WIDGET_GONK 1.42 + if (XRE_GetProcessType() != GeckoProcessType_Default) { 1.43 + NS_WARNING("Most platforms still need an optimized way to share GL cross process."); 1.44 + return new CanvasClient2D(aForwarder, aFlags); 1.45 + } 1.46 +#endif 1.47 + if (aType == CanvasClientGLContext && 1.48 + aForwarder->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL) { 1.49 + aFlags |= TEXTURE_DEALLOCATE_CLIENT; 1.50 + return new CanvasClientSurfaceStream(aForwarder, aFlags); 1.51 + } 1.52 + return new CanvasClient2D(aForwarder, aFlags); 1.53 +} 1.54 + 1.55 +void 1.56 +CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) 1.57 +{ 1.58 + if (mBuffer && 1.59 + (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) { 1.60 + GetForwarder()->RemoveTextureFromCompositable(this, mBuffer); 1.61 + mBuffer = nullptr; 1.62 + } 1.63 + 1.64 + bool bufferCreated = false; 1.65 + if (!mBuffer) { 1.66 + bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE); 1.67 + gfxContentType contentType = isOpaque 1.68 + ? gfxContentType::COLOR 1.69 + : gfxContentType::COLOR_ALPHA; 1.70 + gfxImageFormat format 1.71 + = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType); 1.72 + uint32_t flags = TEXTURE_FLAGS_DEFAULT; 1.73 + if (mTextureFlags & TEXTURE_NEEDS_Y_FLIP) { 1.74 + flags |= TEXTURE_NEEDS_Y_FLIP; 1.75 + } 1.76 + mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format), 1.77 + flags, 1.78 + gfxPlatform::GetPlatform()->GetPreferredCanvasBackend()); 1.79 + MOZ_ASSERT(mBuffer->CanExposeDrawTarget()); 1.80 + mBuffer->AllocateForSurface(aSize); 1.81 + 1.82 + bufferCreated = true; 1.83 + } 1.84 + 1.85 + if (!mBuffer->Lock(OPEN_WRITE_ONLY)) { 1.86 + mBuffer = nullptr; 1.87 + return; 1.88 + } 1.89 + 1.90 + bool updated = false; 1.91 + { 1.92 + // Restrict drawTarget to a scope so that terminates before Unlock. 1.93 + RefPtr<DrawTarget> target = 1.94 + mBuffer->GetAsDrawTarget(); 1.95 + if (target) { 1.96 + aLayer->UpdateTarget(target); 1.97 + updated = true; 1.98 + } 1.99 + } 1.100 + mBuffer->Unlock(); 1.101 + 1.102 + if (bufferCreated && !AddTextureClient(mBuffer)) { 1.103 + mBuffer = nullptr; 1.104 + return; 1.105 + } 1.106 + 1.107 + if (updated) { 1.108 + GetForwarder()->UpdatedTexture(this, mBuffer, nullptr); 1.109 + GetForwarder()->UseTexture(this, mBuffer); 1.110 + } 1.111 +} 1.112 + 1.113 +CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder, 1.114 + TextureFlags aFlags) 1.115 + : CanvasClient(aLayerForwarder, aFlags) 1.116 +{ 1.117 +} 1.118 + 1.119 +void 1.120 +CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) 1.121 +{ 1.122 + aLayer->mGLContext->MakeCurrent(); 1.123 + GLScreenBuffer* screen = aLayer->mGLContext->Screen(); 1.124 + SurfaceStream* stream = nullptr; 1.125 + 1.126 + if (aLayer->mStream) { 1.127 + stream = aLayer->mStream; 1.128 + 1.129 + // Copy our current surface to the current producer surface in our stream, then 1.130 + // call SwapProducer to make a new buffer ready. 1.131 + stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory); 1.132 + stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height)); 1.133 + } else { 1.134 + stream = screen->Stream(); 1.135 + } 1.136 + 1.137 + bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default); 1.138 + bool bufferCreated = false; 1.139 + if (isCrossProcess) { 1.140 +#ifdef MOZ_WIDGET_GONK 1.141 + SharedSurface* surf = stream->SwapConsumer(); 1.142 + if (!surf) { 1.143 + printf_stderr("surf is null post-SwapConsumer!\n"); 1.144 + return; 1.145 + } 1.146 + 1.147 + if (surf->Type() != SharedSurfaceType::Gralloc) { 1.148 + printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!"); 1.149 + MOZ_ASSERT(false); 1.150 + return; 1.151 + } 1.152 + 1.153 + SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf); 1.154 + 1.155 + RefPtr<GrallocTextureClientOGL> grallocTextureClient = 1.156 + static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient()); 1.157 + 1.158 + // If IPDLActor is null means this TextureClient didn't AddTextureClient yet 1.159 + if (!grallocTextureClient->GetIPDLActor()) { 1.160 + grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags); 1.161 + AddTextureClient(grallocTextureClient); 1.162 + } 1.163 + 1.164 + if (grallocTextureClient->GetIPDLActor()) { 1.165 + GetForwarder()->UseTexture(this, grallocTextureClient); 1.166 + } 1.167 +#else 1.168 + printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!"); 1.169 + MOZ_ASSERT(false); 1.170 +#endif 1.171 + } else { 1.172 + if (!mBuffer) { 1.173 + StreamTextureClientOGL* textureClient = 1.174 + new StreamTextureClientOGL(mTextureInfo.mTextureFlags); 1.175 + textureClient->InitWith(stream); 1.176 + mBuffer = textureClient; 1.177 + bufferCreated = true; 1.178 + } 1.179 + 1.180 + if (bufferCreated && !AddTextureClient(mBuffer)) { 1.181 + mBuffer = nullptr; 1.182 + } 1.183 + 1.184 + if (mBuffer) { 1.185 + GetForwarder()->UseTexture(this, mBuffer); 1.186 + } 1.187 + } 1.188 + 1.189 + aLayer->Painted(); 1.190 +} 1.191 + 1.192 +} 1.193 +}