CanvasClient.cpp (3485B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "CanvasClient.h" 8 9 #include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat 10 #include "gfxPlatform.h" // for gfxPlatform 11 #include "mozilla/gfx/BaseSize.h" // for BaseSize 12 #include "mozilla/gfx/gfxVars.h" 13 #include "mozilla/layers/BufferTexture.h" 14 #include "mozilla/layers/CompositableForwarder.h" 15 #include "mozilla/layers/CompositorBridgeChild.h" // for CompositorBridgeChild 16 #include "mozilla/layers/LayersTypes.h" 17 #include "mozilla/layers/OOPCanvasRenderer.h" 18 #include "mozilla/layers/TextureClient.h" // for TextureClient, etc 19 #include "mozilla/layers/TextureClientOGL.h" 20 #include "mozilla/layers/TextureClientRecycleAllocator.h" 21 #include "nsDebug.h" // for printf_stderr, NS_ASSERTION 22 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc 23 24 using namespace mozilla::gfx; 25 using namespace mozilla::gl; 26 27 namespace mozilla { 28 namespace layers { 29 30 void CanvasClient::UseTexture(TextureClient* const aTexture) { 31 MOZ_ASSERT(aTexture); 32 33 const auto isClientNonPremult = 34 bool(mTextureFlags & TextureFlags::NON_PREMULTIPLIED); 35 const auto isTextureNonPremult = 36 bool(aTexture->GetFlags() & TextureFlags::NON_PREMULTIPLIED); 37 MOZ_ALWAYS_TRUE(isTextureNonPremult == isClientNonPremult); 38 39 bool changed = false; 40 41 if (aTexture != mFrontBuffer) { 42 if (!aTexture->IsSharedWithCompositor()) { 43 if (!AddTextureClient(aTexture)) { 44 return; 45 } 46 } 47 changed = true; 48 mFrontBuffer = aTexture; 49 } 50 51 AutoTArray<CompositableForwarder::TimedTextureClient, 1> textures; 52 CompositableForwarder::TimedTextureClient* t = textures.AppendElement(); 53 t->mTextureClient = aTexture; 54 t->mPictureRect = nsIntRect(nsIntPoint(0, 0), aTexture->GetSize()); 55 t->mFrameID = mFrameID; 56 57 GetForwarder()->UseTextures(this, textures); 58 if (changed) { 59 aTexture->SyncWithObject(GetForwarder()->GetSyncObject()); 60 } 61 } 62 63 static constexpr bool kIsWindows = 64 #ifdef XP_WIN 65 true; 66 #else 67 false; 68 #endif 69 70 RefPtr<TextureClient> CanvasClient::CreateTextureClientForCanvas( 71 const gfx::SurfaceFormat aFormat, const gfx::IntSize aSize, 72 const TextureFlags aFlags) { 73 if (kIsWindows) { 74 // With WebRender, host side uses data of TextureClient longer. 75 // Then back buffer reuse in CanvasClient2D::Update() does not work. It 76 // causes a lot of TextureClient allocations. For reducing the allocations, 77 // TextureClientRecycler is used. 78 if (GetForwarder() && GetForwarder()->GetCompositorBackendType() == 79 LayersBackend::LAYERS_WR) { 80 return GetTextureClientRecycler()->CreateOrRecycle( 81 aFormat, aSize, BackendSelector::Canvas, mTextureFlags | aFlags); 82 } 83 return CreateTextureClientForDrawing( 84 aFormat, aSize, BackendSelector::Canvas, mTextureFlags | aFlags); 85 } 86 87 // XXX - We should use CreateTextureClientForDrawing, but we first need 88 // to use double buffering. 89 gfx::BackendType backend = 90 gfxPlatform::GetPlatform()->GetPreferredCanvasBackend(); 91 return TextureClient::CreateForRawBufferAccess( 92 GetForwarder(), aFormat, aSize, backend, mTextureFlags | aFlags); 93 } 94 95 } // namespace layers 96 } // namespace mozilla