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 "WebRenderTextureHost.h"
8
9 #include "mozilla/layers/ImageDataSerializer.h"
10 #include "mozilla/layers/LayersSurfaces.h"
11 #include "mozilla/layers/TextureSourceProvider.h"
12 #include "mozilla/webrender/RenderThread.h"
13 #include "mozilla/webrender/WebRenderAPI.h"
14
15 #ifdef MOZ_WIDGET_ANDROID
16 # include "mozilla/layers/TextureHostOGL.h"
17 #endif
18
19 namespace mozilla::layers {
20
21 class ScheduleHandleRenderTextureOps : public wr::NotificationHandler {
22 public:
ScheduleHandleRenderTextureOps()23 explicit ScheduleHandleRenderTextureOps() {}
24
Notify(wr::Checkpoint aCheckpoint)25 virtual void Notify(wr::Checkpoint aCheckpoint) override {
26 if (aCheckpoint == wr::Checkpoint::FrameTexturesUpdated) {
27 MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
28 wr::RenderThread::Get()->HandleRenderTextureOps();
29 } else {
30 MOZ_ASSERT(aCheckpoint == wr::Checkpoint::TransactionDropped);
31 }
32 }
33
34 protected:
35 };
36
WebRenderTextureHost(const SurfaceDescriptor & aDesc,TextureFlags aFlags,TextureHost * aTexture,wr::ExternalImageId & aExternalImageId)37 WebRenderTextureHost::WebRenderTextureHost(
38 const SurfaceDescriptor& aDesc, TextureFlags aFlags, TextureHost* aTexture,
39 wr::ExternalImageId& aExternalImageId)
40 : TextureHost(aFlags), mWrappedTextureHost(aTexture) {
41 // The wrapped textureHost will be used in WebRender, and the WebRender could
42 // run at another thread. It's hard to control the life-time when gecko
43 // receives PTextureParent destroy message. It's possible that textureHost is
44 // still used by WebRender. So, we only accept the textureHost without
45 // DEALLOCATE_CLIENT flag here. If the buffer deallocation is controlled by
46 // parent, we could do something to make sure the wrapped textureHost is not
47 // used by WebRender and then release it.
48 MOZ_ASSERT(!(aFlags & TextureFlags::DEALLOCATE_CLIENT));
49 MOZ_ASSERT(mWrappedTextureHost);
50
51 MOZ_COUNT_CTOR(WebRenderTextureHost);
52
53 mExternalImageId = Some(aExternalImageId);
54 }
55
~WebRenderTextureHost()56 WebRenderTextureHost::~WebRenderTextureHost() {
57 MOZ_COUNT_DTOR(WebRenderTextureHost);
58 }
59
GetExternalImageKey()60 wr::ExternalImageId WebRenderTextureHost::GetExternalImageKey() {
61 if (IsValid()) {
62 mWrappedTextureHost->EnsureRenderTexture(mExternalImageId);
63 }
64 MOZ_ASSERT(mWrappedTextureHost->mExternalImageId.isSome());
65 return mWrappedTextureHost->mExternalImageId.ref();
66 }
67
IsValid()68 bool WebRenderTextureHost::IsValid() { return mWrappedTextureHost->IsValid(); }
69
Lock()70 bool WebRenderTextureHost::Lock() {
71 MOZ_ASSERT(mWrappedTextureHost->AsBufferTextureHost());
72
73 if (mWrappedTextureHost->AsBufferTextureHost()) {
74 return mWrappedTextureHost->Lock();
75 }
76 return false;
77 }
78
Unlock()79 void WebRenderTextureHost::Unlock() {
80 MOZ_ASSERT(mWrappedTextureHost->AsBufferTextureHost());
81
82 if (mWrappedTextureHost->AsBufferTextureHost()) {
83 mWrappedTextureHost->Unlock();
84 }
85 }
86
PrepareTextureSource(CompositableTextureSourceRef & aTexture)87 void WebRenderTextureHost::PrepareTextureSource(
88 CompositableTextureSourceRef& aTexture) {
89 MOZ_ASSERT(mWrappedTextureHost->AsBufferTextureHost());
90
91 if (mWrappedTextureHost->AsBufferTextureHost()) {
92 mWrappedTextureHost->PrepareTextureSource(aTexture);
93 }
94 }
95
BindTextureSource(CompositableTextureSourceRef & aTexture)96 bool WebRenderTextureHost::BindTextureSource(
97 CompositableTextureSourceRef& aTexture) {
98 MOZ_ASSERT(mWrappedTextureHost->AsBufferTextureHost());
99
100 if (mWrappedTextureHost->AsBufferTextureHost()) {
101 return mWrappedTextureHost->BindTextureSource(aTexture);
102 }
103 return false;
104 }
105
UnbindTextureSource()106 void WebRenderTextureHost::UnbindTextureSource() {
107 if (mWrappedTextureHost->AsBufferTextureHost()) {
108 mWrappedTextureHost->UnbindTextureSource();
109 }
110 // Handle read unlock
111 TextureHost::UnbindTextureSource();
112 }
113
SetTextureSourceProvider(TextureSourceProvider * aProvider)114 void WebRenderTextureHost::SetTextureSourceProvider(
115 TextureSourceProvider* aProvider) {
116 // During using WebRender, only BasicCompositor could exist
117 MOZ_ASSERT(!aProvider || aProvider->AsBasicCompositor());
118 MOZ_ASSERT(mWrappedTextureHost->AsBufferTextureHost());
119
120 if (mWrappedTextureHost->AsBufferTextureHost()) {
121 mWrappedTextureHost->SetTextureSourceProvider(aProvider);
122 }
123 }
124
GetAsSurface()125 already_AddRefed<gfx::DataSourceSurface> WebRenderTextureHost::GetAsSurface() {
126 return mWrappedTextureHost->GetAsSurface();
127 }
128
GetYUVColorSpace() const129 gfx::YUVColorSpace WebRenderTextureHost::GetYUVColorSpace() const {
130 return mWrappedTextureHost->GetYUVColorSpace();
131 }
132
GetColorRange() const133 gfx::ColorRange WebRenderTextureHost::GetColorRange() const {
134 return mWrappedTextureHost->GetColorRange();
135 }
136
GetSize() const137 gfx::IntSize WebRenderTextureHost::GetSize() const {
138 return mWrappedTextureHost->GetSize();
139 }
140
GetFormat() const141 gfx::SurfaceFormat WebRenderTextureHost::GetFormat() const {
142 return mWrappedTextureHost->GetFormat();
143 }
144
NotifyNotUsed()145 void WebRenderTextureHost::NotifyNotUsed() {
146 #ifdef MOZ_WIDGET_ANDROID
147 if (mWrappedTextureHost->AsSurfaceTextureHost()) {
148 wr::RenderThread::Get()->NotifyNotUsed(wr::AsUint64(GetExternalImageKey()));
149 }
150 #endif
151 TextureHost::NotifyNotUsed();
152 }
153
MaybeNotifyForUse(wr::TransactionBuilder & aTxn)154 void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder& aTxn) {
155 #if defined(MOZ_WIDGET_ANDROID)
156 if (mWrappedTextureHost->AsSurfaceTextureHost()) {
157 wr::RenderThread::Get()->NotifyForUse(wr::AsUint64(GetExternalImageKey()));
158 aTxn.Notify(wr::Checkpoint::FrameTexturesUpdated,
159 MakeUnique<ScheduleHandleRenderTextureOps>());
160 }
161 #endif
162 }
163
PrepareForUse()164 void WebRenderTextureHost::PrepareForUse() {
165 if (mWrappedTextureHost->AsSurfaceTextureHost() ||
166 mWrappedTextureHost->AsBufferTextureHost()) {
167 // Call PrepareForUse on render thread.
168 // See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.
169 wr::RenderThread::Get()->PrepareForUse(wr::AsUint64(GetExternalImageKey()));
170 }
171 }
172
GetReadFormat() const173 gfx::SurfaceFormat WebRenderTextureHost::GetReadFormat() const {
174 return mWrappedTextureHost->GetReadFormat();
175 }
176
GetRGBStride()177 int32_t WebRenderTextureHost::GetRGBStride() {
178 gfx::SurfaceFormat format = GetFormat();
179 if (GetFormat() == gfx::SurfaceFormat::YUV) {
180 // XXX this stride is used until yuv image rendering by webrender is used.
181 // Software converted RGB buffers strides are aliened to 16
182 return gfx::GetAlignedStride<16>(
183 GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8));
184 }
185 return ImageDataSerializer::ComputeRGBStride(format, GetSize().width);
186 }
187
HasIntermediateBuffer() const188 bool WebRenderTextureHost::HasIntermediateBuffer() const {
189 return mWrappedTextureHost->HasIntermediateBuffer();
190 }
191
NeedsDeferredDeletion() const192 bool WebRenderTextureHost::NeedsDeferredDeletion() const {
193 return mWrappedTextureHost->NeedsDeferredDeletion();
194 }
195
NumSubTextures()196 uint32_t WebRenderTextureHost::NumSubTextures() {
197 return mWrappedTextureHost->NumSubTextures();
198 }
199
PushResourceUpdates(wr::TransactionBuilder & aResources,ResourceUpdateOp aOp,const Range<wr::ImageKey> & aImageKeys,const wr::ExternalImageId & aExtID)200 void WebRenderTextureHost::PushResourceUpdates(
201 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp,
202 const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) {
203 MOZ_ASSERT(GetExternalImageKey() == aExtID);
204
205 mWrappedTextureHost->PushResourceUpdates(aResources, aOp, aImageKeys, aExtID);
206 }
207
PushDisplayItems(wr::DisplayListBuilder & aBuilder,const wr::LayoutRect & aBounds,const wr::LayoutRect & aClip,wr::ImageRendering aFilter,const Range<wr::ImageKey> & aImageKeys,PushDisplayItemFlagSet aFlags)208 void WebRenderTextureHost::PushDisplayItems(
209 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds,
210 const wr::LayoutRect& aClip, wr::ImageRendering aFilter,
211 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) {
212 MOZ_ASSERT(aImageKeys.length() > 0);
213
214 mWrappedTextureHost->PushDisplayItems(aBuilder, aBounds, aClip, aFilter,
215 aImageKeys, aFlags);
216 }
217
SupportsExternalCompositing(WebRenderBackend aBackend)218 bool WebRenderTextureHost::SupportsExternalCompositing(
219 WebRenderBackend aBackend) {
220 return mWrappedTextureHost->SupportsExternalCompositing(aBackend);
221 }
222
NeedsYFlip() const223 bool WebRenderTextureHost::NeedsYFlip() const {
224 bool yFlip = TextureHost::NeedsYFlip();
225 if (mWrappedTextureHost->AsSurfaceTextureHost()) {
226 MOZ_ASSERT(yFlip);
227 // With WebRender, SurfaceTextureHost always requests y-flip.
228 // But y-flip should not be handled, since
229 // SurfaceTexture.getTransformMatrix() is not handled yet.
230 // See Bug 1507076.
231 yFlip = false;
232 }
233 return yFlip;
234 }
235
SetAcquireFence(mozilla::ipc::FileDescriptor && aFenceFd)236 void WebRenderTextureHost::SetAcquireFence(
237 mozilla::ipc::FileDescriptor&& aFenceFd) {
238 mWrappedTextureHost->SetAcquireFence(std::move(aFenceFd));
239 }
240
SetReleaseFence(mozilla::ipc::FileDescriptor && aFenceFd)241 void WebRenderTextureHost::SetReleaseFence(
242 mozilla::ipc::FileDescriptor&& aFenceFd) {
243 mWrappedTextureHost->SetReleaseFence(std::move(aFenceFd));
244 }
245
GetAndResetReleaseFence()246 mozilla::ipc::FileDescriptor WebRenderTextureHost::GetAndResetReleaseFence() {
247 return mWrappedTextureHost->GetAndResetReleaseFence();
248 }
249
GetAndroidHardwareBuffer() const250 AndroidHardwareBuffer* WebRenderTextureHost::GetAndroidHardwareBuffer() const {
251 return mWrappedTextureHost->GetAndroidHardwareBuffer();
252 }
253
254 } // namespace mozilla::layers
255