DcompSurfaceImage.cpp (6487B)
1 /* -*- Mode: C++; tab-width: 2; 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 "DcompSurfaceImage.h" 7 8 #include "mozilla/ipc/FileDescriptor.h" 9 #include "mozilla/gfx/gfxVars.h" 10 #include "mozilla/layers/CompositorTypes.h" 11 #include "mozilla/layers/LayersSurfaces.h" 12 #include "mozilla/layers/TextureForwarder.h" 13 #include "mozilla/layers/KnowsCompositor.h" 14 #include "mozilla/webrender/RenderDcompSurfaceTextureHost.h" 15 #include "mozilla/webrender/WebRenderAPI.h" 16 17 extern mozilla::LazyLogModule gDcompSurface; 18 #define LOG(...) MOZ_LOG(gDcompSurface, LogLevel::Debug, (__VA_ARGS__)) 19 20 namespace mozilla::layers { 21 22 already_AddRefed<TextureHost> CreateTextureHostDcompSurface( 23 const SurfaceDescriptor& aDesc, ISurfaceAllocator* aDeallocator, 24 LayersBackend aBackend, TextureFlags aFlags) { 25 MOZ_ASSERT(aDesc.type() == SurfaceDescriptor::TSurfaceDescriptorDcompSurface); 26 RefPtr<TextureHost> result = new DcompSurfaceHandleHost( 27 aFlags, aDesc.get_SurfaceDescriptorDcompSurface()); 28 return result.forget(); 29 } 30 31 /* static */ 32 already_AddRefed<TextureClient> DcompSurfaceTexture::CreateTextureClient( 33 HANDLE aHandle, gfx::IntSize aSize, gfx::SurfaceFormat aFormat, 34 KnowsCompositor* aKnowsCompositor) { 35 RefPtr<TextureClient> textureClient = MakeAndAddRef<TextureClient>( 36 new DcompSurfaceTexture(aHandle, aSize, aFormat), TextureFlags::NO_FLAGS, 37 aKnowsCompositor->GetTextureForwarder()); 38 return textureClient.forget(); 39 } 40 41 DcompSurfaceTexture::~DcompSurfaceTexture() { 42 LOG("Destroy DcompSurfaceTexture %p, close handle=%p", this, mHandle); 43 CloseHandle(mHandle); 44 } 45 46 bool DcompSurfaceTexture::Serialize(SurfaceDescriptor& aOutDescriptor) { 47 aOutDescriptor = SurfaceDescriptorDcompSurface(ipc::FileDescriptor(mHandle), 48 mSize, mFormat); 49 return true; 50 } 51 52 void DcompSurfaceTexture::GetSubDescriptor( 53 RemoteDecoderVideoSubDescriptor* aOutDesc) { 54 *aOutDesc = SurfaceDescriptorDcompSurface(ipc::FileDescriptor(mHandle), mSize, 55 mFormat); 56 } 57 58 DcompSurfaceImage::DcompSurfaceImage(HANDLE aHandle, gfx::IntSize aSize, 59 gfx::SurfaceFormat aFormat, 60 KnowsCompositor* aKnowsCompositor) 61 : Image(nullptr, ImageFormat::DCOMP_SURFACE), 62 mTextureClient(DcompSurfaceTexture::CreateTextureClient( 63 aHandle, aSize, aFormat, aKnowsCompositor)) { 64 // Dcomp surface supports DXGI_FORMAT_B8G8R8A8_UNORM, 65 // DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_R16G16B16A16_FLOAT 66 MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8A8 || 67 aFormat == gfx::SurfaceFormat::R8G8B8A8 || 68 aFormat == gfx::SurfaceFormat::R16G16B16A16F); 69 } 70 71 TextureClient* DcompSurfaceImage::GetTextureClient( 72 KnowsCompositor* aKnowsCompositor) { 73 return mTextureClient; 74 } 75 76 DcompSurfaceHandleHost::DcompSurfaceHandleHost( 77 TextureFlags aFlags, const SurfaceDescriptorDcompSurface& aDescriptor) 78 : TextureHost(TextureHostType::DcompSurface, aFlags), 79 mHandle(const_cast<ipc::FileDescriptor&>(aDescriptor.handle()) 80 .TakePlatformHandle()), 81 mSize(aDescriptor.size()), 82 mFormat(aDescriptor.format()) { 83 LOG("Create DcompSurfaceHandleHost %p", this); 84 } 85 86 DcompSurfaceHandleHost::~DcompSurfaceHandleHost() { 87 LOG("Destroy DcompSurfaceHandleHost %p", this); 88 } 89 90 void DcompSurfaceHandleHost::CreateRenderTexture( 91 const wr::ExternalImageId& aExternalImageId) { 92 MOZ_ASSERT(mExternalImageId.isSome()); 93 LOG("DcompSurfaceHandleHost %p CreateRenderTexture, ext-id=%" PRIu64, this, 94 wr::AsUint64(aExternalImageId)); 95 RefPtr<wr::RenderTextureHost> texture = 96 new wr::RenderDcompSurfaceTextureHost(mHandle.get(), mSize, mFormat); 97 wr::RenderThread::Get()->RegisterExternalImage(aExternalImageId, 98 texture.forget()); 99 } 100 101 void DcompSurfaceHandleHost::PushResourceUpdates( 102 wr::TransactionBuilder& aResources, ResourceUpdateOp aOp, 103 const Range<wr::ImageKey>& aImageKeys, 104 const wr::ExternalImageId& aExternalImageId) { 105 if (!gfx::gfxVars::UseWebRenderANGLE()) { 106 MOZ_ASSERT_UNREACHABLE("Unexpected to be called without ANGLE"); 107 return; 108 } 109 MOZ_ASSERT(mHandle); 110 MOZ_ASSERT(aImageKeys.length() == 1); 111 auto method = aOp == TextureHost::ADD_IMAGE 112 ? &wr::TransactionBuilder::AddExternalImage 113 : &wr::TransactionBuilder::UpdateExternalImage; 114 wr::ImageDescriptor descriptor(mSize, GetFormat()); 115 // Prefer TextureExternal unless the backend requires TextureRect. 116 TextureHost::NativeTexturePolicy policy = 117 TextureHost::BackendNativeTexturePolicy(aResources.GetBackendType(), 118 mSize); 119 auto imageType = policy == TextureHost::NativeTexturePolicy::REQUIRE 120 ? wr::ExternalImageType::TextureHandle( 121 wr::ImageBufferKind::TextureRect) 122 : wr::ExternalImageType::TextureHandle( 123 wr::ImageBufferKind::TextureExternal); 124 LOG("DcompSurfaceHandleHost %p PushResourceUpdate, exi-id=%" PRIu64 125 ", type=%s", 126 this, wr::AsUint64(aExternalImageId), 127 policy == TextureHost::NativeTexturePolicy::REQUIRE ? "rect" : "ext"); 128 (aResources.*method)(aImageKeys[0], descriptor, aExternalImageId, imageType, 129 0, /* aNormalizedUvs */ false); 130 } 131 132 void DcompSurfaceHandleHost::PushDisplayItems( 133 wr::DisplayListBuilder& aBuilder, const wr::LayoutRect& aBounds, 134 const wr::LayoutRect& aClip, wr::ImageRendering aFilter, 135 const Range<wr::ImageKey>& aImageKeys, PushDisplayItemFlagSet aFlags) { 136 if (!gfx::gfxVars::UseWebRenderANGLE()) { 137 MOZ_ASSERT_UNREACHABLE("Unexpected to be called without ANGLE"); 138 return; 139 } 140 LOG("DcompSurfaceHandleHost %p PushDisplayItems", this); 141 MOZ_ASSERT(aImageKeys.length() == 1); 142 aBuilder.PushImage( 143 aBounds, aClip, true, false, aFilter, aImageKeys[0], 144 !(mFlags & TextureFlags::NON_PREMULTIPLIED), 145 wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, 146 aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE), 147 SupportsExternalCompositing(aBuilder.GetBackendType())); 148 } 149 150 } // namespace mozilla::layers 151 152 #undef LOG