Bug 1965093 - Add Image::BuildSurfaceDescriptorBuffer fallback implementation. r=gfx-reviewers,jnicol
This patch implements BuildSurfaceDescriptorBuffer for the Image base class. While it does not have the performance benefits of the more specific implementations in the derived classes, it allows the callers to not worry about the edge cases where GetSourceSurface is available. Differential Revision: https://phabricator.services.mozilla.com/D248352
This commit is contained in:
committed by
aosmond@mozilla.com
parent
826bf1fd4b
commit
09959678c3
@@ -290,7 +290,7 @@ mozilla::ipc::IPCResult RemoteDecoderManagerParent::RecvReadback(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// Let's try reading directly into the shmem first to avoid extra copies.
|
||||
// Read directly into the shmem to avoid extra copies, if possible.
|
||||
SurfaceDescriptorBuffer sdb;
|
||||
nsresult rv = image->BuildSurfaceDescriptorBuffer(
|
||||
sdb, Image::BuildSdbFlags::RgbOnly, [&](uint32_t aBufferSize) {
|
||||
@@ -309,43 +309,7 @@ mozilla::ipc::IPCResult RemoteDecoderManagerParent::RecvReadback(
|
||||
if (sdb.data().type() == MemoryOrShmem::TShmem) {
|
||||
DeallocShmem(sdb.data().get_Shmem());
|
||||
}
|
||||
|
||||
if (rv != NS_ERROR_NOT_IMPLEMENTED) {
|
||||
*aResult = null_t();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
// Fallback to reading to a SourceSurface and copying that into a shmem.
|
||||
RefPtr<SourceSurface> source = image->GetAsSourceSurface();
|
||||
if (!source) {
|
||||
*aResult = null_t();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
SurfaceFormat format = source->GetFormat();
|
||||
IntSize size = source->GetSize();
|
||||
size_t length = ImageDataSerializer::ComputeRGBBufferSize(size, format);
|
||||
|
||||
Shmem buffer;
|
||||
if (!length || !AllocShmem(length, &buffer)) {
|
||||
*aResult = null_t();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt = Factory::CreateDrawTargetForData(
|
||||
gfx::BackendType::CAIRO, buffer.get<uint8_t>(), size,
|
||||
ImageDataSerializer::ComputeRGBStride(format, size.width), format);
|
||||
if (!dt) {
|
||||
DeallocShmem(buffer);
|
||||
*aResult = null_t();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
dt->CopySurface(source, IntRect(0, 0, size.width, size.height), IntPoint());
|
||||
dt->Flush();
|
||||
|
||||
*aResult = SurfaceDescriptorBuffer(RGBDescriptor(size, format),
|
||||
MemoryOrShmem(std::move(buffer)));
|
||||
*aResult = null_t();
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,13 @@ MediaResult RemoteVideoDecoderParent::ProcessDecodedData(
|
||||
}
|
||||
return MemoryOrShmem();
|
||||
});
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
if (sdBuffer.data().type() == MemoryOrShmem::TShmem) {
|
||||
DeallocShmem(sdBuffer.data().get_Shmem());
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
sd = sdBuffer;
|
||||
size = image->GetSize();
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "gfxUtils.h" // for gfxUtils
|
||||
#include "GPUVideoImage.h"
|
||||
#include "libyuv.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/ProfilerLabels.h"
|
||||
@@ -239,7 +240,68 @@ ImageContainer::~ImageContainer() {
|
||||
nsresult Image::BuildSurfaceDescriptorBuffer(
|
||||
SurfaceDescriptorBuffer& aSdBuffer, BuildSdbFlags aFlags,
|
||||
const std::function<MemoryOrShmem(uint32_t)>& aAllocate) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
RefPtr<SourceSurface> surface = GetAsSourceSurface();
|
||||
if (NS_WARN_IF(!surface)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> dataSurface = surface->GetDataSurface();
|
||||
if (NS_WARN_IF(!dataSurface)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
DataSourceSurface::ScopedMap map(dataSurface, DataSourceSurface::READ);
|
||||
if (NS_WARN_IF(!map.IsMapped())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
SurfaceFormat format = dataSurface->GetFormat();
|
||||
IntSize size = dataSurface->GetSize();
|
||||
uint8_t* output = nullptr;
|
||||
int32_t stride = 0;
|
||||
nsresult rv = AllocateSurfaceDescriptorBufferRgb(
|
||||
size, format, output, aSdBuffer, stride, aAllocate);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!SwizzleData(map.GetData(), map.GetStride(), format, output,
|
||||
stride, format, size))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult Image::BuildSurfaceDescriptorGPUVideoOrBuffer(
|
||||
SurfaceDescriptor& aSd, BuildSdbFlags aFlags,
|
||||
const Maybe<VideoBridgeSource>& aDest,
|
||||
const std::function<MemoryOrShmem(uint32_t)>& aAllocate,
|
||||
const std::function<void(MemoryOrShmem&&)>& aFree) {
|
||||
if (auto* gpuImage = AsGPUVideoImage()) {
|
||||
if (auto maybeSd = gpuImage->GetDesc()) {
|
||||
if (!aDest ||
|
||||
(maybeSd->type() == SurfaceDescriptor::TSurfaceDescriptorGPUVideo &&
|
||||
maybeSd->get_SurfaceDescriptorGPUVideo()
|
||||
.get_SurfaceDescriptorRemoteDecoder()
|
||||
.source() == aDest)) {
|
||||
aSd = std::move(*maybeSd);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SurfaceDescriptorBuffer sdb;
|
||||
nsresult rv = BuildSurfaceDescriptorBuffer(sdb, aFlags, aAllocate);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (sdb.data().type() != MemoryOrShmem::Type::T__None) {
|
||||
aFree(std::move(sdb.data()));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
aSd = std::move(sdb);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
Maybe<SurfaceDescriptor> Image::GetDesc() { return GetDescFromTexClient(); }
|
||||
|
||||
@@ -69,6 +69,7 @@ class D3D11YCbCrRecycleAllocator;
|
||||
class MacIOSurfaceRecycleAllocator;
|
||||
#endif
|
||||
class SurfaceDescriptorBuffer;
|
||||
enum class VideoBridgeSource : uint8_t;
|
||||
|
||||
struct ImageBackendData {
|
||||
virtual ~ImageBackendData() = default;
|
||||
@@ -145,6 +146,16 @@ class Image {
|
||||
SurfaceDescriptorBuffer& aSdBuffer, BuildSdbFlags aFlags,
|
||||
const std::function<MemoryOrShmem(uint32_t)>& aAllocate);
|
||||
|
||||
/**
|
||||
* Get a SurfaceDescriptorGPUVideo if possible, with the source matching aDest
|
||||
* if given. Otherwise copy the data into a SurfaceDescriptorBuffer.
|
||||
*/
|
||||
nsresult BuildSurfaceDescriptorGPUVideoOrBuffer(
|
||||
SurfaceDescriptor& aSd, BuildSdbFlags aFlags,
|
||||
const Maybe<VideoBridgeSource>& aDest,
|
||||
const std::function<MemoryOrShmem(uint32_t)>& aAllocate,
|
||||
const std::function<void(MemoryOrShmem&&)>& aFree);
|
||||
|
||||
virtual bool IsValid() const { return true; }
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user