RenderDMABUFTextureHost.cpp (4027B)
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 "RenderDMABUFTextureHost.h" 8 9 #include "GLContextEGL.h" 10 #include "mozilla/gfx/Logging.h" 11 #include "ScopedGLHelpers.h" 12 13 namespace mozilla::wr { 14 15 RenderDMABUFTextureHost::RenderDMABUFTextureHost(DMABufSurface* aSurface) 16 : mSurface(aSurface) { 17 MOZ_COUNT_CTOR_INHERITED(RenderDMABUFTextureHost, RenderTextureHost); 18 } 19 20 RenderDMABUFTextureHost::~RenderDMABUFTextureHost() { 21 MOZ_COUNT_DTOR_INHERITED(RenderDMABUFTextureHost, RenderTextureHost); 22 DeleteTextureHandle(); 23 } 24 25 wr::WrExternalImage RenderDMABUFTextureHost::Lock(uint8_t aChannelIndex, 26 gl::GLContext* aGL) { 27 const gfx::IntSize size(mSurface->GetWidth(aChannelIndex), 28 mSurface->GetHeight(aChannelIndex)); 29 30 // Wayland native compositor doesn't use textures so pass zero 31 // there. It saves GPU resources. 32 if (!aGL) { 33 return NativeTextureToWrExternalImage(0, 0.0, 0.0, 34 static_cast<float>(size.width), 35 static_cast<float>(size.height)); 36 } 37 38 if (mGL.get() != aGL) { 39 if (mGL) { 40 // This should not happen. EGLImage is created only in 41 // parent process. 42 MOZ_ASSERT_UNREACHABLE("Unexpected GL context"); 43 return InvalidToWrExternalImage(); 44 } 45 mGL = aGL; 46 } 47 48 if (!mGL || !mGL->MakeCurrent()) { 49 return InvalidToWrExternalImage(); 50 } 51 52 if (!mSurface->GetTexture(aChannelIndex)) { 53 if (!mSurface->CreateTexture(mGL, aChannelIndex)) { 54 return InvalidToWrExternalImage(); 55 } 56 ActivateBindAndTexParameteri(mGL, LOCAL_GL_TEXTURE0, LOCAL_GL_TEXTURE_2D, 57 mSurface->GetTexture(aChannelIndex)); 58 } 59 60 if (auto texture = mSurface->GetTexture(aChannelIndex)) { 61 mSurface->MaybeSemaphoreWait(texture); 62 } 63 64 return NativeTextureToWrExternalImage( 65 mSurface->GetTexture(aChannelIndex), 0.0, 0.0, 66 static_cast<float>(size.width), static_cast<float>(size.height)); 67 } 68 69 gfx::IntSize RenderDMABUFTextureHost::GetSize(uint8_t aChannelIndex) const { 70 MOZ_ASSERT(mSurface); 71 MOZ_ASSERT((mSurface->GetTextureCount() == 0) 72 ? (aChannelIndex == mSurface->GetTextureCount()) 73 : (aChannelIndex < mSurface->GetTextureCount())); 74 75 if (!mSurface) { 76 return gfx::IntSize(); 77 } 78 return gfx::IntSize(mSurface->GetWidth(aChannelIndex), 79 mSurface->GetHeight(aChannelIndex)); 80 } 81 82 void RenderDMABUFTextureHost::Unlock() {} 83 84 void RenderDMABUFTextureHost::DeleteTextureHandle() { 85 mSurface->ReleaseTextures(); 86 } 87 88 void RenderDMABUFTextureHost::ClearCachedResources() { 89 DeleteTextureHandle(); 90 mGL = nullptr; 91 } 92 93 bool RenderDMABUFTextureHost::MapPlane(RenderCompositor* aCompositor, 94 uint8_t aChannelIndex, 95 PlaneInfo& aPlaneInfo) { 96 if (mSurface->GetAsDMABufSurfaceYUV()) { 97 // DMABufSurfaceYUV is not supported. 98 return false; 99 } 100 101 const RefPtr<gfx::SourceSurface> surface = mSurface->GetAsSourceSurface(); 102 if (!surface) { 103 return false; 104 } 105 106 const RefPtr<gfx::DataSourceSurface> dataSurface = surface->GetDataSurface(); 107 if (!dataSurface) { 108 return false; 109 } 110 111 gfx::DataSourceSurface::MappedSurface map; 112 if (!dataSurface->Map(gfx::DataSourceSurface::MapType::READ, &map)) { 113 return false; 114 } 115 116 mReadback = dataSurface; 117 aPlaneInfo.mSize = gfx::IntSize(mSurface->GetWidth(), mSurface->GetHeight()); 118 aPlaneInfo.mStride = map.mStride; 119 aPlaneInfo.mData = map.mData; 120 121 return true; 122 } 123 124 void RenderDMABUFTextureHost::UnmapPlanes() { 125 if (mReadback) { 126 mReadback->Unmap(); 127 mReadback = nullptr; 128 } 129 } 130 131 } // namespace mozilla::wr