WebRenderTextureHost.cpp (7476B)
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 #ifdef XP_WIN 20 # include "mozilla/layers/TextureD3D11.h" 21 #endif 22 23 namespace mozilla::layers { 24 25 class ScheduleHandleRenderTextureOps : public wr::NotificationHandler { 26 public: 27 explicit ScheduleHandleRenderTextureOps() {} 28 29 virtual void Notify(wr::Checkpoint aCheckpoint) override { 30 if (aCheckpoint == wr::Checkpoint::FrameTexturesUpdated) { 31 MOZ_ASSERT(wr::RenderThread::IsInRenderThread()); 32 wr::RenderThread::Get()->HandleRenderTextureOps(); 33 } else { 34 MOZ_ASSERT(aCheckpoint == wr::Checkpoint::TransactionDropped); 35 } 36 } 37 38 protected: 39 }; 40 41 WebRenderTextureHost::WebRenderTextureHost( 42 TextureFlags aFlags, TextureHost* aTexture, 43 const wr::ExternalImageId& aExternalImageId) 44 : TextureHost(TextureHostType::Unknown, aFlags), 45 mWrappedTextureHost(aTexture) { 46 MOZ_ASSERT(mWrappedTextureHost); 47 // The wrapped textureHost will be used in WebRender, and the WebRender could 48 // run at another thread. It's hard to control the life-time when gecko 49 // receives PTextureParent destroy message. It's possible that textureHost is 50 // still used by WebRender. So, we only accept the textureHost without 51 // DEALLOCATE_CLIENT flag here. If the buffer deallocation is controlled by 52 // parent, we could do something to make sure the wrapped textureHost is not 53 // used by WebRender and then release it. 54 MOZ_ASSERT(!(aFlags & TextureFlags::DEALLOCATE_CLIENT)); 55 MOZ_COUNT_CTOR(WebRenderTextureHost); 56 57 mExternalImageId = Some(aExternalImageId); 58 } 59 60 WebRenderTextureHost::~WebRenderTextureHost() { 61 MOZ_COUNT_DTOR(WebRenderTextureHost); 62 } 63 64 wr::ExternalImageId WebRenderTextureHost::GetExternalImageKey() { 65 if (IsValid()) { 66 mWrappedTextureHost->EnsureRenderTexture(mExternalImageId); 67 } 68 MOZ_ASSERT(mWrappedTextureHost->mExternalImageId.isSome()); 69 return mWrappedTextureHost->mExternalImageId.ref(); 70 } 71 72 bool WebRenderTextureHost::IsValid() { return mWrappedTextureHost->IsValid(); } 73 74 void WebRenderTextureHost::UnbindTextureSource() { 75 if (mWrappedTextureHost->AsBufferTextureHost()) { 76 mWrappedTextureHost->UnbindTextureSource(); 77 } 78 // Handle read unlock 79 TextureHost::UnbindTextureSource(); 80 } 81 82 already_AddRefed<gfx::DataSourceSurface> WebRenderTextureHost::GetAsSurface( 83 gfx::DataSourceSurface* aSurface) { 84 return mWrappedTextureHost->GetAsSurface(aSurface); 85 } 86 87 gfx::ColorDepth WebRenderTextureHost::GetColorDepth() const { 88 return mWrappedTextureHost->GetColorDepth(); 89 } 90 91 gfx::YUVColorSpace WebRenderTextureHost::GetYUVColorSpace() const { 92 return mWrappedTextureHost->GetYUVColorSpace(); 93 } 94 95 gfx::ColorRange WebRenderTextureHost::GetColorRange() const { 96 return mWrappedTextureHost->GetColorRange(); 97 } 98 99 gfx::IntSize WebRenderTextureHost::GetSize() const { 100 return mWrappedTextureHost->GetSize(); 101 } 102 103 gfx::SurfaceFormat WebRenderTextureHost::GetFormat() const { 104 return mWrappedTextureHost->GetFormat(); 105 } 106 107 bool WebRenderTextureHost::NeedsYFlip() const { 108 return mWrappedTextureHost->NeedsYFlip(); 109 } 110 111 void WebRenderTextureHost::MaybeDestroyRenderTexture() { 112 // WebRenderTextureHost does not create RenderTexture, then 113 // WebRenderTextureHost does not need to destroy RenderTexture. 114 mExternalImageId = Nothing(); 115 } 116 117 void WebRenderTextureHost::NotifyNotUsed() { 118 #ifdef MOZ_WIDGET_ANDROID 119 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper, 120 // NotifyNotUsed() is handled by SurfaceTextureHost. 121 if (IsWrappingSurfaceTextureHost() && 122 !mWrappedTextureHost->AsRemoteTextureHostWrapper()) { 123 wr::RenderThread::Get()->NotifyNotUsed(GetExternalImageKey()); 124 } 125 #endif 126 mWrappedTextureHost->NotifyNotUsed(); 127 TextureHost::NotifyNotUsed(); 128 } 129 130 void WebRenderTextureHost::MaybeNotifyForUse(wr::TransactionBuilder& aTxn) { 131 #if defined(MOZ_WIDGET_ANDROID) 132 if (IsWrappingSurfaceTextureHost() && 133 !mWrappedTextureHost->AsRemoteTextureHostWrapper()) { 134 wr::RenderThread::Get()->NotifyForUse(GetExternalImageKey()); 135 aTxn.Notify(wr::Checkpoint::FrameTexturesUpdated, 136 MakeUnique<ScheduleHandleRenderTextureOps>()); 137 } 138 #endif 139 } 140 141 bool WebRenderTextureHost::IsWrappingSurfaceTextureHost() { 142 return mWrappedTextureHost->IsWrappingSurfaceTextureHost(); 143 } 144 145 void WebRenderTextureHost::PrepareForUse() { 146 // When SurfaceTextureHost is wrapped by RemoteTextureHostWrapper, 147 // PrepareForUse() is handled by SurfaceTextureHost. 148 if ((IsWrappingSurfaceTextureHost() && 149 !mWrappedTextureHost->AsRemoteTextureHostWrapper()) || 150 mWrappedTextureHost->AsBufferTextureHost()) { 151 // Call PrepareForUse on render thread. 152 // See RenderAndroidSurfaceTextureHostOGL::PrepareForUse. 153 wr::RenderThread::Get()->PrepareForUse(GetExternalImageKey()); 154 } 155 } 156 157 gfx::SurfaceFormat WebRenderTextureHost::GetReadFormat() const { 158 return mWrappedTextureHost->GetReadFormat(); 159 } 160 161 int32_t WebRenderTextureHost::GetRGBStride() { 162 gfx::SurfaceFormat format = GetFormat(); 163 if (GetFormat() == gfx::SurfaceFormat::YUV420) { 164 // XXX this stride is used until yuv image rendering by webrender is used. 165 // Software converted RGB buffers strides are aliened to 16 166 return gfx::GetAlignedStride<16>( 167 GetSize().width, BytesPerPixel(gfx::SurfaceFormat::B8G8R8A8)); 168 } 169 return ImageDataSerializer::ComputeRGBStride(format, GetSize().width); 170 } 171 172 bool WebRenderTextureHost::NeedsDeferredDeletion() const { 173 return mWrappedTextureHost->NeedsDeferredDeletion(); 174 } 175 176 uint32_t WebRenderTextureHost::NumSubTextures() { 177 return mWrappedTextureHost->NumSubTextures(); 178 } 179 180 void WebRenderTextureHost::PushResourceUpdates( 181 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp, 182 const Range<wr::ImageKey>& aImageKeys, const wr::ExternalImageId& aExtID) { 183 MOZ_ASSERT(GetExternalImageKey() == aExtID); 184 185 mWrappedTextureHost->PushResourceUpdates(aResources, aOp, aImageKeys, aExtID); 186 } 187 188 void WebRenderTextureHost::PushDisplayItems( 189 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds, 190 const wr::LayoutRect& aClip, wr::ImageRendering aFilter, 191 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) { 192 MOZ_ASSERT(aImageKeys.length() > 0); 193 194 mWrappedTextureHost->PushDisplayItems(aBuilder, aBounds, aClip, aFilter, 195 aImageKeys, aFlags); 196 } 197 198 bool WebRenderTextureHost::SupportsExternalCompositing( 199 WebRenderBackend aBackend) { 200 return mWrappedTextureHost->SupportsExternalCompositing(aBackend); 201 } 202 203 void WebRenderTextureHost::SetReadFence(Fence* aReadFence) { 204 return mWrappedTextureHost->SetReadFence(aReadFence); 205 } 206 207 AndroidHardwareBuffer* WebRenderTextureHost::GetAndroidHardwareBuffer() const { 208 return mWrappedTextureHost->GetAndroidHardwareBuffer(); 209 } 210 211 TextureHostType WebRenderTextureHost::GetTextureHostType() { 212 return mWrappedTextureHost->GetTextureHostType(); 213 } 214 215 } // namespace mozilla::layers