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 "WebRenderTextureHost.h"
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"
15 #ifdef MOZ_WIDGET_ANDROID
16 # include "mozilla/layers/TextureHostOGL.h"
19 namespace mozilla::layers
{
21 class ScheduleHandleRenderTextureOps
: public wr::NotificationHandler
{
23 explicit ScheduleHandleRenderTextureOps() {}
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();
30 MOZ_ASSERT(aCheckpoint
== wr::Checkpoint::TransactionDropped
);
37 WebRenderTextureHost::WebRenderTextureHost(
38 TextureFlags aFlags
, TextureHost
* aTexture
,
39 const wr::ExternalImageId
& aExternalImageId
)
40 : TextureHost(TextureHostType::Unknown
, aFlags
),
41 mWrappedTextureHost(aTexture
) {
42 MOZ_ASSERT(mWrappedTextureHost
);
43 // The wrapped textureHost will be used in WebRender, and the WebRender could
44 // run at another thread. It's hard to control the life-time when gecko
45 // receives PTextureParent destroy message. It's possible that textureHost is
46 // still used by WebRender. So, we only accept the textureHost without
47 // DEALLOCATE_CLIENT flag here. If the buffer deallocation is controlled by
48 // parent, we could do something to make sure the wrapped textureHost is not
49 // used by WebRender and then release it.
50 MOZ_ASSERT(!(aFlags
& TextureFlags::DEALLOCATE_CLIENT
));
51 MOZ_COUNT_CTOR(WebRenderTextureHost
);
53 mExternalImageId
= Some(aExternalImageId
);
56 WebRenderTextureHost::~WebRenderTextureHost() {
57 MOZ_COUNT_DTOR(WebRenderTextureHost
);
60 wr::ExternalImageId
WebRenderTextureHost::GetExternalImageKey() {
62 mWrappedTextureHost
->EnsureRenderTexture(mExternalImageId
);
64 MOZ_ASSERT(mWrappedTextureHost
->mExternalImageId
.isSome());
65 return mWrappedTextureHost
->mExternalImageId
.ref();
68 bool WebRenderTextureHost::IsValid() { return mWrappedTextureHost
->IsValid(); }
70 void WebRenderTextureHost::UnbindTextureSource() {
71 if (mWrappedTextureHost
->IsWrappingBufferTextureHost()) {
72 mWrappedTextureHost
->UnbindTextureSource();
75 TextureHost::UnbindTextureSource();
78 already_AddRefed
<gfx::DataSourceSurface
> WebRenderTextureHost::GetAsSurface() {
79 return mWrappedTextureHost
->GetAsSurface();
82 gfx::ColorDepth
WebRenderTextureHost::GetColorDepth() const {
83 return mWrappedTextureHost
->GetColorDepth();
86 gfx::YUVColorSpace
WebRenderTextureHost::GetYUVColorSpace() const {
87 return mWrappedTextureHost
->GetYUVColorSpace();
90 gfx::ColorRange
WebRenderTextureHost::GetColorRange() const {
91 return mWrappedTextureHost
->GetColorRange();
94 gfx::IntSize
WebRenderTextureHost::GetSize() const {
95 return mWrappedTextureHost
->GetSize();
98 gfx::SurfaceFormat
WebRenderTextureHost::GetFormat() const {
99 return mWrappedTextureHost
->GetFormat();
102 void WebRenderTextureHost::NotifyNotUsed() {
103 #ifdef MOZ_WIDGET_ANDROID
104 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
105 // NotifyNotUsed() is handled by SurfaceTextureHost.
106 if (IsWrappingSurfaceTextureHost() &&
107 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) {
108 wr::RenderThread::Get()->NotifyNotUsed(GetExternalImageKey());
111 if (mWrappedTextureHost
->AsRemoteTextureHostWrapper()) {
112 mWrappedTextureHost
->NotifyNotUsed();
114 TextureHost::NotifyNotUsed();
117 void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder
& aTxn
) {
118 #if defined(MOZ_WIDGET_ANDROID)
119 if (IsWrappingSurfaceTextureHost() &&
120 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) {
121 wr::RenderThread::Get()->NotifyForUse(GetExternalImageKey());
122 aTxn
.Notify(wr::Checkpoint::FrameTexturesUpdated
,
123 MakeUnique
<ScheduleHandleRenderTextureOps
>());
128 bool WebRenderTextureHost::IsWrappingBufferTextureHost() {
129 return mWrappedTextureHost
->IsWrappingBufferTextureHost();
132 bool WebRenderTextureHost::IsWrappingSurfaceTextureHost() {
133 return mWrappedTextureHost
->IsWrappingSurfaceTextureHost();
136 void WebRenderTextureHost::PrepareForUse() {
137 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
138 // PrepareForUse() is handled by SurfaceTextureHost.
139 if ((IsWrappingSurfaceTextureHost() &&
140 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) ||
141 mWrappedTextureHost
->IsWrappingBufferTextureHost()) {
142 // Call PrepareForUse on render thread.
143 // See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.
144 wr::RenderThread::Get()->PrepareForUse(GetExternalImageKey());
148 gfx::SurfaceFormat
WebRenderTextureHost::GetReadFormat() const {
149 return mWrappedTextureHost
->GetReadFormat();
152 int32_t WebRenderTextureHost::GetRGBStride() {
153 gfx::SurfaceFormat format
= GetFormat();
154 if (GetFormat() == gfx::SurfaceFormat::YUV
) {
155 // XXX this stride is used until yuv image rendering by webrender is used.
156 // Software converted RGB buffers strides are aliened to 16
157 return gfx::GetAlignedStride
<16>(
158 GetSize().width
, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8
));
160 return ImageDataSerializer::ComputeRGBStride(format
, GetSize().width
);
163 bool WebRenderTextureHost::NeedsDeferredDeletion() const {
164 return mWrappedTextureHost
->NeedsDeferredDeletion();
167 uint32_t WebRenderTextureHost::NumSubTextures() {
168 return mWrappedTextureHost
->NumSubTextures();
171 void WebRenderTextureHost::PushResourceUpdates(
172 wr::TransactionBuilder
& aResources
, ResourceUpdateOp aOp
,
173 const Range
<wr::ImageKey
>& aImageKeys
, const wr::ExternalImageId
& aExtID
) {
174 MOZ_ASSERT(GetExternalImageKey() == aExtID
);
176 mWrappedTextureHost
->PushResourceUpdates(aResources
, aOp
, aImageKeys
, aExtID
);
179 void WebRenderTextureHost::PushDisplayItems(
180 wr::DisplayListBuilder
& aBuilder
, const wr::LayoutRect
& aBounds
,
181 const wr::LayoutRect
& aClip
, wr::ImageRendering aFilter
,
182 const Range
<wr::ImageKey
>& aImageKeys
, PushDisplayItemFlagSet aFlags
) {
183 MOZ_ASSERT(aImageKeys
.length() > 0);
185 mWrappedTextureHost
->PushDisplayItems(aBuilder
, aBounds
, aClip
, aFilter
,
189 bool WebRenderTextureHost::SupportsExternalCompositing(
190 WebRenderBackend aBackend
) {
191 return mWrappedTextureHost
->SupportsExternalCompositing(aBackend
);
194 void WebRenderTextureHost::SetAcquireFence(
195 mozilla::ipc::FileDescriptor
&& aFenceFd
) {
196 mWrappedTextureHost
->SetAcquireFence(std::move(aFenceFd
));
199 void WebRenderTextureHost::SetReleaseFence(
200 mozilla::ipc::FileDescriptor
&& aFenceFd
) {
201 mWrappedTextureHost
->SetReleaseFence(std::move(aFenceFd
));
204 mozilla::ipc::FileDescriptor
WebRenderTextureHost::GetAndResetReleaseFence() {
205 return mWrappedTextureHost
->GetAndResetReleaseFence();
208 AndroidHardwareBuffer
* WebRenderTextureHost::GetAndroidHardwareBuffer() const {
209 return mWrappedTextureHost
->GetAndroidHardwareBuffer();
212 TextureHostType
WebRenderTextureHost::GetTextureHostType() {
213 return mWrappedTextureHost
->GetTextureHostType();
216 } // namespace mozilla::layers