gfx/layers/client/CanvasClient.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:1fac7f2530b8
1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "mozilla/layers/CanvasClient.h"
7 #include "ClientCanvasLayer.h" // for ClientCanvasLayer
8 #include "GLContext.h" // for GLContext
9 #include "GLScreenBuffer.h" // for GLScreenBuffer
10 #include "SurfaceStream.h" // for SurfaceStream
11 #include "SurfaceTypes.h" // for SurfaceStreamHandle
12 #include "gfx2DGlue.h" // for ImageFormatToSurfaceFormat
13 #include "gfxPlatform.h" // for gfxPlatform
14 #include "mozilla/gfx/BaseSize.h" // for BaseSize
15 #include "mozilla/layers/CompositableForwarder.h"
16 #include "mozilla/layers/GrallocTextureClient.h"
17 #include "mozilla/layers/LayersTypes.h"
18 #include "mozilla/layers/TextureClient.h" // for TextureClient, etc
19 #include "mozilla/layers/TextureClientOGL.h"
20 #include "nsAutoPtr.h" // for nsRefPtr
21 #include "nsDebug.h" // for printf_stderr, NS_ASSERTION
22 #include "nsXULAppAPI.h" // for XRE_GetProcessType, etc
23 #ifdef MOZ_WIDGET_GONK
24 #include "SharedSurfaceGralloc.h"
25 #endif
26
27 using namespace mozilla::gfx;
28 using namespace mozilla::gl;
29
30 namespace mozilla {
31 namespace layers {
32
33 /* static */ TemporaryRef<CanvasClient>
34 CanvasClient::CreateCanvasClient(CanvasClientType aType,
35 CompositableForwarder* aForwarder,
36 TextureFlags aFlags)
37 {
38 #ifndef MOZ_WIDGET_GONK
39 if (XRE_GetProcessType() != GeckoProcessType_Default) {
40 NS_WARNING("Most platforms still need an optimized way to share GL cross process.");
41 return new CanvasClient2D(aForwarder, aFlags);
42 }
43 #endif
44 if (aType == CanvasClientGLContext &&
45 aForwarder->GetCompositorBackendType() == LayersBackend::LAYERS_OPENGL) {
46 aFlags |= TEXTURE_DEALLOCATE_CLIENT;
47 return new CanvasClientSurfaceStream(aForwarder, aFlags);
48 }
49 return new CanvasClient2D(aForwarder, aFlags);
50 }
51
52 void
53 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
54 {
55 if (mBuffer &&
56 (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
57 GetForwarder()->RemoveTextureFromCompositable(this, mBuffer);
58 mBuffer = nullptr;
59 }
60
61 bool bufferCreated = false;
62 if (!mBuffer) {
63 bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
64 gfxContentType contentType = isOpaque
65 ? gfxContentType::COLOR
66 : gfxContentType::COLOR_ALPHA;
67 gfxImageFormat format
68 = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType);
69 uint32_t flags = TEXTURE_FLAGS_DEFAULT;
70 if (mTextureFlags & TEXTURE_NEEDS_Y_FLIP) {
71 flags |= TEXTURE_NEEDS_Y_FLIP;
72 }
73 mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format),
74 flags,
75 gfxPlatform::GetPlatform()->GetPreferredCanvasBackend());
76 MOZ_ASSERT(mBuffer->CanExposeDrawTarget());
77 mBuffer->AllocateForSurface(aSize);
78
79 bufferCreated = true;
80 }
81
82 if (!mBuffer->Lock(OPEN_WRITE_ONLY)) {
83 mBuffer = nullptr;
84 return;
85 }
86
87 bool updated = false;
88 {
89 // Restrict drawTarget to a scope so that terminates before Unlock.
90 RefPtr<DrawTarget> target =
91 mBuffer->GetAsDrawTarget();
92 if (target) {
93 aLayer->UpdateTarget(target);
94 updated = true;
95 }
96 }
97 mBuffer->Unlock();
98
99 if (bufferCreated && !AddTextureClient(mBuffer)) {
100 mBuffer = nullptr;
101 return;
102 }
103
104 if (updated) {
105 GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
106 GetForwarder()->UseTexture(this, mBuffer);
107 }
108 }
109
110 CanvasClientSurfaceStream::CanvasClientSurfaceStream(CompositableForwarder* aLayerForwarder,
111 TextureFlags aFlags)
112 : CanvasClient(aLayerForwarder, aFlags)
113 {
114 }
115
116 void
117 CanvasClientSurfaceStream::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
118 {
119 aLayer->mGLContext->MakeCurrent();
120 GLScreenBuffer* screen = aLayer->mGLContext->Screen();
121 SurfaceStream* stream = nullptr;
122
123 if (aLayer->mStream) {
124 stream = aLayer->mStream;
125
126 // Copy our current surface to the current producer surface in our stream, then
127 // call SwapProducer to make a new buffer ready.
128 stream->CopySurfaceToProducer(aLayer->mTextureSurface, aLayer->mFactory);
129 stream->SwapProducer(aLayer->mFactory, gfx::IntSize(aSize.width, aSize.height));
130 } else {
131 stream = screen->Stream();
132 }
133
134 bool isCrossProcess = !(XRE_GetProcessType() == GeckoProcessType_Default);
135 bool bufferCreated = false;
136 if (isCrossProcess) {
137 #ifdef MOZ_WIDGET_GONK
138 SharedSurface* surf = stream->SwapConsumer();
139 if (!surf) {
140 printf_stderr("surf is null post-SwapConsumer!\n");
141 return;
142 }
143
144 if (surf->Type() != SharedSurfaceType::Gralloc) {
145 printf_stderr("Unexpected non-Gralloc SharedSurface in IPC path!");
146 MOZ_ASSERT(false);
147 return;
148 }
149
150 SharedSurface_Gralloc* grallocSurf = SharedSurface_Gralloc::Cast(surf);
151
152 RefPtr<GrallocTextureClientOGL> grallocTextureClient =
153 static_cast<GrallocTextureClientOGL*>(grallocSurf->GetTextureClient());
154
155 // If IPDLActor is null means this TextureClient didn't AddTextureClient yet
156 if (!grallocTextureClient->GetIPDLActor()) {
157 grallocTextureClient->SetTextureFlags(mTextureInfo.mTextureFlags);
158 AddTextureClient(grallocTextureClient);
159 }
160
161 if (grallocTextureClient->GetIPDLActor()) {
162 GetForwarder()->UseTexture(this, grallocTextureClient);
163 }
164 #else
165 printf_stderr("isCrossProcess, but not MOZ_WIDGET_GONK! Someone needs to write some code!");
166 MOZ_ASSERT(false);
167 #endif
168 } else {
169 if (!mBuffer) {
170 StreamTextureClientOGL* textureClient =
171 new StreamTextureClientOGL(mTextureInfo.mTextureFlags);
172 textureClient->InitWith(stream);
173 mBuffer = textureClient;
174 bufferCreated = true;
175 }
176
177 if (bufferCreated && !AddTextureClient(mBuffer)) {
178 mBuffer = nullptr;
179 }
180
181 if (mBuffer) {
182 GetForwarder()->UseTexture(this, mBuffer);
183 }
184 }
185
186 aLayer->Painted();
187 }
188
189 }
190 }

mercurial