Bug 1919083 - [ci] Enable os-integration variant for more suites, r=jmaher
[gecko.git] / gfx / layers / ShareableCanvasRenderer.cpp
blobe9ac1374081512ed064d9dff5979a6248db5bb87
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/. */
7 #include "ShareableCanvasRenderer.h"
9 #include "mozilla/dom/WebGLTypes.h"
10 #include "mozilla/gfx/2D.h"
11 #include "mozilla/layers/TextureClientSharedSurface.h"
12 #include "mozilla/layers/CompositableForwarder.h"
13 #include "mozilla/layers/TextureForwarder.h"
15 #include "ClientWebGLContext.h"
16 #include "gfxUtils.h"
17 #include "GLScreenBuffer.h"
18 #include "nsICanvasRenderingContextInternal.h"
19 #include "SharedSurfaceGL.h"
21 using namespace mozilla::gfx;
23 namespace mozilla {
24 namespace layers {
26 ShareableCanvasRenderer::ShareableCanvasRenderer() {
27 MOZ_COUNT_CTOR(ShareableCanvasRenderer);
30 ShareableCanvasRenderer::~ShareableCanvasRenderer() {
31 MOZ_COUNT_DTOR(ShareableCanvasRenderer);
33 mFrontBufferFromDesc = nullptr;
34 DisconnectClient();
37 void ShareableCanvasRenderer::Initialize(const CanvasRendererData& aData) {
38 CanvasRenderer::Initialize(aData);
39 mCanvasClient = nullptr;
42 void ShareableCanvasRenderer::ClearCachedResources() {
43 CanvasRenderer::ClearCachedResources();
45 if (mCanvasClient) {
46 mCanvasClient->Clear();
50 void ShareableCanvasRenderer::DisconnectClient() {
51 if (mCanvasClient) {
52 mCanvasClient->OnDetach();
53 mCanvasClient = nullptr;
57 RefPtr<layers::TextureClient> ShareableCanvasRenderer::GetFrontBufferFromDesc(
58 const layers::SurfaceDescriptor& desc, TextureFlags flags) {
59 if (mFrontBufferFromDesc && mFrontBufferDesc == desc)
60 return mFrontBufferFromDesc;
61 mFrontBufferFromDesc = nullptr;
63 // Test the validity of aAllocator
64 const auto& compositableForwarder = GetForwarder();
65 if (!compositableForwarder) {
66 return nullptr;
68 const auto& textureForwarder = compositableForwarder->GetTextureForwarder();
70 auto format = gfx::SurfaceFormat::R8G8B8X8;
71 if (!mData.mIsOpaque) {
72 format = gfx::SurfaceFormat::R8G8B8A8;
74 if (!mData.mIsAlphaPremult) {
75 flags |= TextureFlags::NON_PREMULTIPLIED;
79 mFrontBufferFromDesc = SharedSurfaceTextureData::CreateTextureClient(
80 desc, format, mData.mSize, flags, textureForwarder);
81 mFrontBufferDesc = desc;
82 return mFrontBufferFromDesc;
85 void ShareableCanvasRenderer::UpdateCompositableClient() {
86 if (!CreateCompositable()) {
87 return;
90 if (!IsDirty()) {
91 const auto context = mData.GetContext();
92 if (!context) {
93 return;
95 const auto& forwarder = GetForwarder();
96 RefPtr<FwdTransactionTracker> tracker =
97 context->UseCompositableForwarder(forwarder);
98 if (forwarder && tracker) {
99 forwarder->TrackFwdTransaction(tracker);
101 return;
103 ResetDirty();
105 const auto context = mData.GetContext();
106 if (!context) return;
107 const auto& provider = context->GetBufferProvider();
108 const auto& forwarder = GetForwarder();
110 // -
112 auto flags = TextureFlags::IMMUTABLE;
113 if (!YIsDown()) {
114 flags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
116 if (IsOpaque()) {
117 flags |= TextureFlags::IS_OPAQUE;
120 // -
122 const auto fnGetExistingTc =
123 [&](const Maybe<SurfaceDescriptor>& aDesc,
124 bool& aOutLostFrontTexture) -> RefPtr<TextureClient> {
125 if (aDesc) {
126 return GetFrontBufferFromDesc(*aDesc, flags);
128 if (provider) {
129 if (!provider->SetKnowsCompositor(forwarder, aOutLostFrontTexture)) {
130 gfxCriticalNote << "BufferProvider::SetForwarder failed";
131 return nullptr;
133 if (aOutLostFrontTexture) {
134 return nullptr;
137 return provider->GetTextureClient();
139 return nullptr;
142 // -
144 const auto fnMakeTcFromSnapshot = [&]() -> RefPtr<TextureClient> {
145 const auto& size = mData.mSize;
147 auto contentType = gfxContentType::COLOR;
148 if (!mData.mIsOpaque) {
149 contentType = gfxContentType::COLOR_ALPHA;
151 const auto surfaceFormat =
152 gfxPlatform::GetPlatform()->Optimal2DFormatForContent(contentType);
154 const auto tc =
155 mCanvasClient->CreateTextureClientForCanvas(surfaceFormat, size, flags);
156 if (!tc) {
157 return nullptr;
161 TextureClientAutoLock tcLock(tc, OpenMode::OPEN_WRITE_ONLY);
162 if (!tcLock.Succeeded()) {
163 return nullptr;
166 const RefPtr<DrawTarget> dt = tc->BorrowDrawTarget();
168 const bool requireAlphaPremult = false;
169 auto borrowed = BorrowSnapshot(requireAlphaPremult);
170 if (!borrowed) {
171 return nullptr;
173 dt->CopySurface(borrowed->mSurf, borrowed->mSurf->GetRect(), {0, 0});
176 return tc;
179 // -
182 FirePreTransactionCallback();
184 const auto desc = context->GetFrontBuffer(nullptr);
185 if (desc &&
186 desc->type() == SurfaceDescriptor::TSurfaceDescriptorRemoteTexture) {
187 const auto& forwarder = GetForwarder();
188 const auto& textureDesc = desc->get_SurfaceDescriptorRemoteTexture();
189 if (!mData.mIsAlphaPremult) {
190 flags |= TextureFlags::NON_PREMULTIPLIED;
192 EnsurePipeline();
193 RefPtr<FwdTransactionTracker> tracker =
194 context->UseCompositableForwarder(forwarder);
195 if (tracker) {
196 flags |= TextureFlags::WAIT_FOR_REMOTE_TEXTURE_OWNER;
198 forwarder->UseRemoteTexture(mCanvasClient, textureDesc.textureId(),
199 textureDesc.ownerId(), mData.mSize, flags,
200 tracker);
201 FireDidTransactionCallback();
202 return;
205 EnsurePipeline();
207 // Let's see if we can get a no-copy TextureClient from the canvas.
208 bool lostFrontTexture = false;
209 auto tc = fnGetExistingTc(desc, lostFrontTexture);
210 if (lostFrontTexture) {
211 // Device reset could cause this.
212 return;
214 if (!tc) {
215 // Otherwise, snapshot the surface and copy into a TexClient.
216 tc = fnMakeTcFromSnapshot();
218 if (tc != mFrontBufferFromDesc) {
219 mFrontBufferFromDesc = nullptr;
222 if (!tc) {
223 NS_WARNING("Couldn't make TextureClient for CanvasRenderer.");
224 return;
227 mCanvasClient->UseTexture(tc);
229 FireDidTransactionCallback();
233 } // namespace layers
234 } // namespace mozilla