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
->AsBufferTextureHost()) {
72 mWrappedTextureHost
->UnbindTextureSource();
75 TextureHost::UnbindTextureSource();
78 already_AddRefed
<gfx::DataSourceSurface
> WebRenderTextureHost::GetAsSurface(
79 gfx::DataSourceSurface
* aSurface
) {
80 return mWrappedTextureHost
->GetAsSurface(aSurface
);
83 gfx::ColorDepth
WebRenderTextureHost::GetColorDepth() const {
84 return mWrappedTextureHost
->GetColorDepth();
87 gfx::YUVColorSpace
WebRenderTextureHost::GetYUVColorSpace() const {
88 return mWrappedTextureHost
->GetYUVColorSpace();
91 gfx::ColorRange
WebRenderTextureHost::GetColorRange() const {
92 return mWrappedTextureHost
->GetColorRange();
95 gfx::IntSize
WebRenderTextureHost::GetSize() const {
96 return mWrappedTextureHost
->GetSize();
99 gfx::SurfaceFormat
WebRenderTextureHost::GetFormat() const {
100 return mWrappedTextureHost
->GetFormat();
103 void WebRenderTextureHost::MaybeDestroyRenderTexture() {
104 // WebRenderTextureHost does not create RenderTexture, then
105 // WebRenderTextureHost does not need to destroy RenderTexture.
106 mExternalImageId
= Nothing();
109 void WebRenderTextureHost::NotifyNotUsed() {
110 #ifdef MOZ_WIDGET_ANDROID
111 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
112 // NotifyNotUsed() is handled by SurfaceTextureHost.
113 if (IsWrappingSurfaceTextureHost() &&
114 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) {
115 wr::RenderThread::Get()->NotifyNotUsed(GetExternalImageKey());
118 if (mWrappedTextureHost
->AsRemoteTextureHostWrapper() ||
119 mWrappedTextureHost
->AsTextureHostWrapperD3D11()) {
120 mWrappedTextureHost
->NotifyNotUsed();
122 TextureHost::NotifyNotUsed();
125 void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder
& aTxn
) {
126 #if defined(MOZ_WIDGET_ANDROID)
127 if (IsWrappingSurfaceTextureHost() &&
128 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) {
129 wr::RenderThread::Get()->NotifyForUse(GetExternalImageKey());
130 aTxn
.Notify(wr::Checkpoint::FrameTexturesUpdated
,
131 MakeUnique
<ScheduleHandleRenderTextureOps
>());
136 bool WebRenderTextureHost::IsWrappingSurfaceTextureHost() {
137 return mWrappedTextureHost
->IsWrappingSurfaceTextureHost();
140 void WebRenderTextureHost::PrepareForUse() {
141 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper,
142 // PrepareForUse() is handled by SurfaceTextureHost.
143 if ((IsWrappingSurfaceTextureHost() &&
144 !mWrappedTextureHost
->AsRemoteTextureHostWrapper()) ||
145 mWrappedTextureHost
->AsBufferTextureHost()) {
146 // Call PrepareForUse on render thread.
147 // See RenderAndroidSurfaceTextureHostOGL::PrepareForUse.
148 wr::RenderThread::Get()->PrepareForUse(GetExternalImageKey());
152 gfx::SurfaceFormat
WebRenderTextureHost::GetReadFormat() const {
153 return mWrappedTextureHost
->GetReadFormat();
156 int32_t WebRenderTextureHost::GetRGBStride() {
157 gfx::SurfaceFormat format
= GetFormat();
158 if (GetFormat() == gfx::SurfaceFormat::YUV
) {
159 // XXX this stride is used until yuv image rendering by webrender is used.
160 // Software converted RGB buffers strides are aliened to 16
161 return gfx::GetAlignedStride
<16>(
162 GetSize().width
, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8
));
164 return ImageDataSerializer::ComputeRGBStride(format
, GetSize().width
);
167 bool WebRenderTextureHost::NeedsDeferredDeletion() const {
168 return mWrappedTextureHost
->NeedsDeferredDeletion();
171 uint32_t WebRenderTextureHost::NumSubTextures() {
172 return mWrappedTextureHost
->NumSubTextures();
175 void WebRenderTextureHost::PushResourceUpdates(
176 wr::TransactionBuilder
& aResources
, ResourceUpdateOp aOp
,
177 const Range
<wr::ImageKey
>& aImageKeys
, const wr::ExternalImageId
& aExtID
) {
178 MOZ_ASSERT(GetExternalImageKey() == aExtID
);
180 mWrappedTextureHost
->PushResourceUpdates(aResources
, aOp
, aImageKeys
, aExtID
);
183 void WebRenderTextureHost::PushDisplayItems(
184 wr::DisplayListBuilder
& aBuilder
, const wr::LayoutRect
& aBounds
,
185 const wr::LayoutRect
& aClip
, wr::ImageRendering aFilter
,
186 const Range
<wr::ImageKey
>& aImageKeys
, PushDisplayItemFlagSet aFlags
) {
187 MOZ_ASSERT(aImageKeys
.length() > 0);
189 mWrappedTextureHost
->PushDisplayItems(aBuilder
, aBounds
, aClip
, aFilter
,
193 bool WebRenderTextureHost::SupportsExternalCompositing(
194 WebRenderBackend aBackend
) {
195 return mWrappedTextureHost
->SupportsExternalCompositing(aBackend
);
198 void WebRenderTextureHost::SetAcquireFence(
199 mozilla::ipc::FileDescriptor
&& aFenceFd
) {
200 mWrappedTextureHost
->SetAcquireFence(std::move(aFenceFd
));
203 void WebRenderTextureHost::SetReleaseFence(
204 mozilla::ipc::FileDescriptor
&& aFenceFd
) {
205 mWrappedTextureHost
->SetReleaseFence(std::move(aFenceFd
));
208 mozilla::ipc::FileDescriptor
WebRenderTextureHost::GetAndResetReleaseFence() {
209 return mWrappedTextureHost
->GetAndResetReleaseFence();
212 AndroidHardwareBuffer
* WebRenderTextureHost::GetAndroidHardwareBuffer() const {
213 return mWrappedTextureHost
->GetAndroidHardwareBuffer();
216 TextureHostType
WebRenderTextureHost::GetTextureHostType() {
217 return mWrappedTextureHost
->GetTextureHostType();
220 } // namespace mozilla::layers