- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 71 %
- : 87 %
- : 87 %
- : 87 %
- : 71 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 71 %
- : 87 %
- : 87 %
- : 80 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 71 %
- : 87 %
- : 85 %
- : 87 %
- : 80 %
- : 87 %
- : 87 %
- : 87 %
- : 71 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 80 %
- : 80 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 80 %
- : 71 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 71 %
- : 85 %
- : 85 %
- : 71 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 71 %
- : 87 %
- : 85 %
- : 71 %
- : 71 %
- : 85 %
- : 87 %
- : 87 %
- : 80 %
- : 71 %
- : 87 %
- : 87 %
- : 71 %
- : 87 %
- : 87 %
- : 71 %
- : 87 %
- : 87 %
- : 85 %
- : 80 %
- : 80 %
- : 80 %
- : 80 %
- : 87 %
- : 80 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 80 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 87 %
- : 85 %
- : 87 %
- : 87 %
- : 87 %
- : 85 %
- : 87 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 73 %
- : 73 %
- : 73 %
- : 70 %
- : 81 %
- : 71 %
- : 81 %
- : 81 %
- : 85 %
- : 85 %
- : 85 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 85 %
- : 78 %
- : 85 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 85 %
- : 85 %
- : 78 %
- : 78 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 85 %
- : 85 %
- : 93 %
- : 78 %
- : 78 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 85 %
- : 85 %
- : 85 %
- : 78 %
- : 85 %
- : 78 %
- : 85 %
- : 85 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 78 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 93 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 93 %
- : 100 %
- : 100 %
- : 93 %
- : 100 %
- : 100 %
- : 100 %
- : 93 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 100 %
- : 72 %
- : 71 %
- : 81 %
- : 57 %
- : 67 %
- : 62 %
- : 62 %
- : 71 %
- : 62 %
- : 62 %
- : 62 %
- : 62 %
- : 72 %
- : 71 %
- : 56 %
- : 66 %
- : 72 %
- : 72 %
- : 62 %
- : 71 %
- : 71 %
Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SourceSurfaceWebgl.h"
#include "DrawTargetWebglInternal.h"
#include "WebGLBuffer.h"
#include "mozilla/gfx/Swizzle.h"
namespace mozilla::gfx {
SourceSurfaceWebgl::SourceSurfaceWebgl(DrawTargetWebgl* aDT)
: mFormat(aDT->GetFormat()),
mSize(aDT->GetSize()),
mDT(aDT),
mSharedContext(aDT->mSharedContext) {}
SourceSurfaceWebgl::SourceSurfaceWebgl(
const RefPtr<SharedContextWebgl>& aSharedContext)
: mSharedContext(aSharedContext) {}
SourceSurfaceWebgl::~SourceSurfaceWebgl() {
if (mHandle) {
// Signal that the texture handle is not being used now.
mHandle->ClearSurface();
}
if (mReadBuffer) {
if (RefPtr<SharedContextWebgl> sharedContext = {mSharedContext}) {
sharedContext->RemoveSnapshotPBO(this, mReadBuffer.forget());
}
mReadBuffer = nullptr;
}
}
// Read back the contents of the target or texture handle for data use. This
// may attempt a readback into a PBO for performance, unless forced to
// immediately read into data.
inline bool SourceSurfaceWebgl::EnsureData(bool aForce, uint8_t* aData,
int32_t aStride) {
if (mData) {
if (aData) {
DataSourceSurface::ScopedMap map(mData, MapType::READ);
if (!map.IsMapped()) {
return false;
}
SwizzleData(map.GetData(), map.GetStride(), mFormat, aData, aStride,
mFormat, mSize);
}
return true;
}
if (mReadBuffer) {
// If there is a pending PBO readback, then copy the contents of the PBO.
if (RefPtr<SharedContextWebgl> sharedContext = {mSharedContext}) {
mData = sharedContext->ReadSnapshotFromPBO(mReadBuffer, mFormat, mSize,
aData, aStride);
mOwnsData = !mData || !aData;
sharedContext->RemoveSnapshotPBO(this, mReadBuffer.forget());
}
mReadBuffer = nullptr;
return !!mData;
}
if (RefPtr<DrawTargetWebgl> dt = {mDT}) {
if (!aForce) {
mReadBuffer = dt->ReadSnapshotIntoPBO(this);
}
if (!mReadBuffer) {
mData = dt->ReadSnapshot(aData, aStride);
mOwnsData = !mData || !aData;
}
} else if (mHandle) {
// Assume that the target changed, so there should be a texture handle
// holding a copy. Try to read data from the copy since we can't read
// from the target.
if (RefPtr<SharedContextWebgl> sharedContext = {mSharedContext}) {
if (!aForce) {
mReadBuffer = sharedContext->ReadSnapshotIntoPBO(this, mHandle);
}
if (!mReadBuffer) {
mData = sharedContext->ReadSnapshot(mHandle, aData, aStride);
mOwnsData = !mData || !aData;
}
}
}
return mData || mReadBuffer;
}
bool SourceSurfaceWebgl::ReadDataInto(uint8_t* aData, int32_t aStride) {
return EnsureData(true, aData, aStride);
}
bool SourceSurfaceWebgl::ForceReadFromPBO() {
if (mReadBuffer && EnsureData()) {
MOZ_ASSERT(!mReadBuffer);
return true;
}
return false;
}
uint8_t* SourceSurfaceWebgl::GetData() {
if (!EnsureData()) {
return nullptr;
}
if (!mOwnsData) {
mData = Factory::CopyDataSourceSurface(mData);
mOwnsData = true;
}
return mData ? mData->GetData() : nullptr;
}
int32_t SourceSurfaceWebgl::Stride() {
if (!EnsureData()) {
return 0;
}
return mData->Stride();
}
bool SourceSurfaceWebgl::Map(MapType aType, MappedSurface* aMappedSurface) {
if (!EnsureData()) {
return false;
}
if (!mOwnsData && aType != MapType::READ) {
mData = Factory::CopyDataSourceSurface(mData);
mOwnsData = true;
}
return mData && mData->Map(aType, aMappedSurface);
}
void SourceSurfaceWebgl::Unmap() {
if (mData) {
mData->Unmap();
}
}
// Handler for when the owner DrawTargetWebgl is about to modify its internal
// framebuffer, and so this snapshot must be copied into a new texture, if
// possible, or read back into data, if necessary, to preserve this particular
// version of the framebuffer.
void SourceSurfaceWebgl::DrawTargetWillChange(bool aNeedHandle) {
RefPtr<DrawTargetWebgl> dt(mDT);
if (!dt) {
MOZ_ASSERT_UNREACHABLE("No DrawTargetWebgl for SourceSurfaceWebgl");
return;
}
// Only try to copy into a new texture handle if we don't already have data.
// However, we still might need to immediately draw this snapshot to a WebGL
// target, which would require a subsequent upload, so also copy into a new
// handle even if we already have data in that case since it is faster than
// uploading.
if ((aNeedHandle || (!mData && !mReadBuffer)) && !mHandle) {
// Prefer copying the framebuffer to a texture if possible.
mHandle = dt->CopySnapshot();
if (mHandle) {
// Link this surface to the handle.
mHandle->SetSurface(this);
} else {
// If that fails, then try to just read the data to a surface.
EnsureData(false);
}
}
mDT = nullptr;
}
// Handler for when the owner DrawTargetWebgl is itself being destroyed and
// needs to transfer ownership of its internal backing texture to the snapshot.
void SourceSurfaceWebgl::GiveTexture(RefPtr<TextureHandle> aHandle) {
// If we get here, then the target still points to this surface as its
// snapshot and needs to hand off its backing texture before it is destroyed.
MOZ_ASSERT(mDT);
MOZ_ASSERT(!mHandle);
mHandle = aHandle.forget();
mHandle->SetSurface(this);
mDT = nullptr;
}
void SourceSurfaceWebgl::SetHandle(TextureHandle* aHandle) {
MOZ_ASSERT(!mHandle);
mFormat = aHandle->GetFormat();
mSize = aHandle->GetSize();
mHandle = aHandle;
mHandle->SetSurface(this);
}
// Handler for when the owner DrawTargetWebgl is destroying the cached texture
// handle that has been allocated for this snapshot, or if the surface has
// uploaded data.
void SourceSurfaceWebgl::OnUnlinkTexture(SharedContextWebgl* aContext,
TextureHandle* aHandle, bool aForce) {
// If the snapshot was mapped before the target changed, we may have read
// data instead of holding a copied texture handle. If subsequently we then
// try to draw with this snapshot, we might have allocated an external texture
// handle in the texture cache that still links to this snapshot and can cause
// us to end up here inside OnUnlinkTexture.
if (mHandle != aHandle) {
return;
}
if (!mData && !mReadBuffer) {
if (!aForce) {
mReadBuffer = aContext->ReadSnapshotIntoPBO(this, mHandle);
}
if (!mReadBuffer) {
mData = aContext->ReadSnapshot(mHandle);
mOwnsData = true;
}
}
mHandle = nullptr;
}
already_AddRefed<SourceSurface> SourceSurfaceWebgl::ExtractSubrect(
const IntRect& aRect) {
// Ensure the subrect is actually in bounds.
if (aRect.IsEmpty() || !GetRect().Contains(aRect)) {
return nullptr;
}
RefPtr<TextureHandle> subHandle;
RefPtr<SharedContextWebgl> sharedContext;
if (RefPtr<DrawTargetWebgl> dt = {mDT}) {
// If this is still a snapshot linked to a target, then copy from the
// target.
subHandle = dt->CopySnapshot(aRect);
sharedContext = dt->mSharedContext;
} else if (mHandle) {
// Otherwise, we have a handle, but we need to verify it is still linked to
// a valid context.
sharedContext = mSharedContext;
if (sharedContext) {
// Try to copy directly from the handle using the context.
subHandle = sharedContext->CopySnapshot(aRect, mHandle);
}
}
if (subHandle && sharedContext) {
RefPtr<SourceSurfaceWebgl> surface = new SourceSurfaceWebgl(sharedContext);
surface->SetHandle(subHandle);
return surface.forget();
}
return nullptr;
}
} // namespace mozilla::gfx