Bug 1655000 - Use same function for getting size as reading into buffer. r=lsalzman

Previously we called GetFrontBufferSize, alloc'd a buffer, and called
FrontBufferSnapshotInto to read into the buffer.
Now, call FrontBufferSnapshotInto({}) to get size, and then alloc and
pass pointer to newly alloc'd data into
FrontBufferSnapshotInto(Some(ptr)).
Using the same function for both means that logic can't diverge and
cause mismatch bugs.

Differential Revision: https://phabricator.services.mozilla.com/D113611
This commit is contained in:
Jeff Gilbert 2021-04-28 20:38:23 +00:00
Родитель e607a45a9c
Коммит 9317ccff9a
5 изменённых файлов: 47 добавлений и 24 удалений

Просмотреть файл

@ -866,7 +866,9 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
auto snapshot = [&]() -> RefPtr<gfx::DataSourceSurface> {
const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
const auto surfSize = inProcess->GetFrontBufferSize();
const auto maybeSize = inProcess->FrontBufferSnapshotInto({});
if (!maybeSize) return nullptr;
const auto& surfSize = *maybeSize;
const auto stride = surfSize.x * 4;
const auto byteSize = stride * surfSize.y;
const auto surf = fnNewSurf(surfSize);
@ -880,7 +882,12 @@ RefPtr<gfx::SourceSurface> ClientWebGLContext::GetFrontBufferSnapshot(
}
MOZ_RELEASE_ASSERT(map.GetStride() == static_cast<int64_t>(stride));
auto range = Range<uint8_t>{map.GetData(), byteSize};
if (!inProcess->FrontBufferSnapshotInto(range)) return nullptr;
if (!inProcess->FrontBufferSnapshotInto(Some(range))) {
gfxCriticalNote << "ClientWebGLContext::GetFrontBufferSnapshot: "
"FrontBufferSnapshotInto(some) failed after "
"FrontBufferSnapshotInto(none)";
return nullptr;
}
}
return surf;
}

Просмотреть файл

@ -178,8 +178,7 @@ class HostWebGLContext final : public SupportsWeakPtr {
// -
uvec2 GetFrontBufferSize() const { return mContext->DrawingBufferSize(); }
bool FrontBufferSnapshotInto(Range<uint8_t> dest) const {
Maybe<uvec2> FrontBufferSnapshotInto(Maybe<Range<uint8_t>> dest) const {
return mContext->FrontBufferSnapshotInto(dest);
}

Просмотреть файл

@ -959,9 +959,14 @@ Maybe<layers::SurfaceDescriptor> WebGLContext::GetFrontBuffer(
return front->ToSurfaceDescriptor();
}
bool WebGLContext::FrontBufferSnapshotInto(Range<uint8_t> dest) {
Maybe<uvec2> WebGLContext::FrontBufferSnapshotInto(
const Maybe<Range<uint8_t>> maybeDest) {
const auto& front = mSwapChain.FrontBuffer();
if (!front) return false;
if (!front) return {};
const auto& size = front->mDesc.size;
const auto ret = Some(*uvec2::FromSize(size));
if (!maybeDest) return ret;
const auto& dest = *maybeDest;
// -
@ -1012,14 +1017,19 @@ bool WebGLContext::FrontBufferSnapshotInto(Range<uint8_t> dest) {
// -
const auto& size = front->mDesc.size;
const size_t stride = size.width * 4;
MOZ_ASSERT(dest.length() == stride * size.height);
const size_t srcByteCount = stride * size.height;
const auto dstByteCount = dest.length();
if (srcByteCount != dstByteCount) {
gfxCriticalError() << "FrontBufferSnapshotInto: srcByteCount:"
<< srcByteCount << " != dstByteCount:" << dstByteCount;
return {};
}
gl->fReadPixels(0, 0, size.width, size.height, LOCAL_GL_RGBA,
LOCAL_GL_UNSIGNED_BYTE, dest.begin().get());
gfxUtils::ConvertBGRAtoRGBA(dest.begin().get(), stride * size.height);
gfxUtils::ConvertBGRAtoRGBA(dest.begin().get(), dstByteCount);
return true;
return ret;
}
void WebGLContext::ClearVRSwapChain() { mWebVRSwapChain.ClearPool(); }

Просмотреть файл

@ -491,7 +491,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
public:
void Present(WebGLFramebuffer*, layers::TextureType, const bool webvr);
RefPtr<gfx::DataSourceSurface> GetFrontBufferSnapshot();
bool FrontBufferSnapshotInto(Range<uint8_t>);
Maybe<uvec2> FrontBufferSnapshotInto(Maybe<Range<uint8_t>>);
Maybe<layers::SurfaceDescriptor> GetFrontBuffer(WebGLFramebuffer*,
const bool webvr);

Просмотреть файл

@ -88,22 +88,29 @@ IPCResult WebGLParent::RecvGetFrontBufferSnapshot(
webgl::FrontBufferSnapshotIpc* const ret) {
*ret = {};
const auto surfSize = mHost->GetFrontBufferSize();
const auto byteSize = 4 * surfSize.x * surfSize.y;
const auto maybeSize = mHost->FrontBufferSnapshotInto({});
if (maybeSize) {
const auto& surfSize = *maybeSize;
const auto byteSize = 4 * surfSize.x * surfSize.y;
auto shmem = webgl::RaiiShmem::Alloc(
this, byteSize, mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC);
if (!shmem) {
NS_WARNING("Failed to alloc shmem for RecvGetFrontBufferSnapshot.");
return IPC_FAIL(this, "Failed to allocate shmem for result");
}
auto shmem = webgl::RaiiShmem::Alloc(
this, byteSize,
mozilla::ipc::SharedMemory::SharedMemoryType::TYPE_BASIC);
if (!shmem) {
NS_WARNING("Failed to alloc shmem for RecvGetFrontBufferSnapshot.");
return IPC_FAIL(this, "Failed to allocate shmem for result");
}
const auto range = shmem.ByteRange();
auto retSize = surfSize;
if (!mHost->FrontBufferSnapshotInto(range)) {
retSize = {0, 0}; // Zero means failure.
const auto range = shmem.ByteRange();
auto retSize = surfSize;
if (!mHost->FrontBufferSnapshotInto(Some(range))) {
gfxCriticalNote << "WebGLParent::RecvGetFrontBufferSnapshot: "
"FrontBufferSnapshotInto(some) failed after "
"FrontBufferSnapshotInto(none)";
retSize = {0, 0}; // Zero means failure.
}
*ret = {retSize, shmem.Extract()};
}
*ret = {retSize, shmem.Extract()};
return IPC_OK();
}