Backed out 8 changesets (bug 1829026) for causing several mochitest failures. CLOSED TREE

Backed out changeset 790ba6aa65e4 (bug 1829026)
Backed out changeset 2ff1f5f41380 (bug 1829026)
Backed out changeset de6ddf5eb2a7 (bug 1829026)
Backed out changeset 773e7b31ac6e (bug 1829026)
Backed out changeset e09602ab096d (bug 1829026)
Backed out changeset fe16d4ac1049 (bug 1829026)
Backed out changeset c0fe0aea86c2 (bug 1829026)
Backed out changeset 53d6f69055f1 (bug 1829026)
This commit is contained in:
Cosmin Sabou 2023-12-05 16:08:36 +02:00
Родитель 882e879a4e
Коммит 6f5d4853e5
49 изменённых файлов: 1053 добавлений и 2036 удалений

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

@ -64,6 +64,7 @@
#include "nsIMemoryReporter.h"
#include "nsStyleUtil.h"
#include "CanvasImageCache.h"
#include "DrawTargetWebgl.h"
#include <algorithm>
@ -1355,31 +1356,7 @@ bool CanvasRenderingContext2D::CopyBufferProvider(
return false;
}
// If the DT has a writeable backing buffer, then try to use ReadInto to
// directly read into it. This can use fewer copies than CopySurface if the
// snapshot is not immediately available in a readable buffer.
bool success = false;
{
uint8_t* data = nullptr;
gfx::IntSize size;
int32_t stride = 0;
SurfaceFormat format = SurfaceFormat::UNKNOWN;
if (aTarget.LockBits(&data, &size, &stride, &format)) {
uint8_t* destPtr =
data + aCopyRect.y * stride + aCopyRect.x * BytesPerPixel(format);
if (RefPtr<DataSourceSurface> destSurface =
gfx::Factory::CreateWrappingDataSourceSurface(
destPtr, stride, aCopyRect.Size(), format)) {
success = snapshot->ReadInto(destSurface, aCopyRect);
}
aTarget.ReleaseBits(data);
}
}
if (!success) {
aTarget.CopySurface(snapshot, aCopyRect, IntPoint());
}
aTarget.CopySurface(snapshot, aCopyRect, IntPoint());
aOld.ReturnSnapshot(snapshot.forget());
return true;
}
@ -1674,22 +1651,13 @@ bool CanvasRenderingContext2D::TryAcceleratedTarget(
if (!mAllowAcceleration || GetEffectiveWillReadFrequently()) {
return false;
}
aOutDT = DrawTargetWebgl::Create(GetSize(), GetSurfaceFormat());
if (!aOutDT) {
return false;
}
if (!mCanvasElement) {
return false;
}
WindowRenderer* renderer = WindowRendererFromCanvasElement(mCanvasElement);
if (!renderer) {
return false;
}
aOutProvider = PersistentBufferProviderAccelerated::Create(
GetSize(), GetSurfaceFormat(), renderer->AsKnowsCompositor());
if (!aOutProvider) {
return false;
}
aOutDT = aOutProvider->BorrowDrawTarget(IntRect());
MOZ_ASSERT(aOutDT);
return !!aOutDT;
aOutProvider = new PersistentBufferProviderAccelerated(aOutDT);
return true;
}
bool CanvasRenderingContext2D::TrySharedTarget(

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

@ -3494,8 +3494,27 @@ void ClientWebGLContext::BufferData(GLenum target,
});
}
void ClientWebGLContext::RawBufferData(GLenum target, const uint8_t* srcBytes,
size_t srcLen, GLenum usage) {
const FuncScope funcScope(*this, "bufferData");
const auto srcBuffer =
srcBytes ? RawBuffer<>({srcBytes, srcLen}) : RawBuffer<>(srcLen);
Run<RPROC(BufferData)>(target, srcBuffer, usage);
}
////
void ClientWebGLContext::RawBufferSubData(GLenum target,
WebGLsizeiptr dstByteOffset,
const uint8_t* srcBytes,
size_t srcLen, bool unsynchronized) {
const FuncScope funcScope(*this, "bufferSubData");
Run<RPROC(BufferSubData)>(target, dstByteOffset,
RawBuffer<>({srcBytes, srcLen}), unsynchronized);
}
void ClientWebGLContext::BufferSubData(GLenum target,
WebGLsizeiptr dstByteOffset,
const dom::ArrayBuffer& src) {
@ -4528,6 +4547,38 @@ void ClientWebGLContext::TexImage(uint8_t funcDims, GLenum imageTarget,
}
}
void ClientWebGLContext::RawTexImage(uint32_t level, GLenum respecFormat,
uvec3 offset, const webgl::PackingInfo& pi,
webgl::TexUnpackBlobDesc&& desc) const {
const FuncScope funcScope(*this, "tex(Sub)Image[23]D");
if (IsContextLost()) return;
if (desc.sd) {
// Shmems are stored in Buffer surface descriptors. We need to ensure first
// that all queued commands are flushed and then send the Shmem over IPDL.
const auto& sd = *(desc.sd);
if (sd.type() == layers::SurfaceDescriptor::TSurfaceDescriptorBuffer &&
sd.get_SurfaceDescriptorBuffer().data().type() ==
layers::MemoryOrShmem::TShmem) {
const auto& inProcess = mNotLost->inProcess;
if (inProcess) {
inProcess->TexImage(level, respecFormat, offset, pi, desc);
} else {
const auto& child = mNotLost->outOfProcess;
child->FlushPendingCmds();
(void)child->SendTexImage(level, respecFormat, offset, pi,
std::move(desc));
}
} else {
NS_WARNING(
"RawTexImage with SurfaceDescriptor only supports "
"SurfaceDescriptorBuffer with Shmem");
}
return;
}
Run<RPROC(TexImage)>(level, respecFormat, offset, pi, desc);
}
// -
void ClientWebGLContext::CompressedTexImage(bool sub, uint8_t funcDims,
@ -5130,6 +5181,30 @@ bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
return true;
}
bool ClientWebGLContext::DoReadPixels(const webgl::ReadPixelsDesc& desc,
const mozilla::ipc::Shmem& shmem) const {
const auto notLost =
mNotLost; // Hold a strong-ref to prevent LoseContext=>UAF.
if (!notLost) return false;
const auto& inProcess = notLost->inProcess;
if (inProcess) {
const auto& shmemBytes = shmem.Range<uint8_t>();
inProcess->ReadPixelsInto(desc, shmemBytes);
return true;
}
const auto& child = notLost->outOfProcess;
child->FlushPendingCmds();
webgl::ReadPixelsResultIpc res = {};
// We assume the input is an unsafe shmem which won't be consumed by this
// request. Since SendReadPixels expects a Shmem rvalue, we must create a copy
// to provide it that can be consumed instead of the original descriptor.
mozilla::ipc::Shmem dest = shmem;
if (!child->SendReadPixels(desc, dest, &res)) {
res = {};
}
return res.byteStride > 0;
}
bool ClientWebGLContext::ReadPixels_SharedPrecheck(
dom::CallerType aCallerType, ErrorResult& out_error) const {
if (IsContextLost()) return false;

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

@ -41,6 +41,10 @@ class OwningHTMLCanvasElementOrOffscreenCanvas;
class WebGLChild;
} // namespace dom
namespace gfx {
class DrawTargetWebgl;
}
namespace webgl {
class AvailabilityRunnable;
class TexUnpackBlob;
@ -749,6 +753,7 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
friend class webgl::ObjectJS;
friend class webgl::ProgramKeepAlive;
friend class webgl::ShaderKeepAlive;
friend class gfx::DrawTargetWebgl;
// ----------------------------- Lifetime and DOM ---------------------------
public:
@ -1088,6 +1093,8 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
RefPtr<gfx::DataSourceSurface> BackBufferSnapshot();
[[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&,
Range<uint8_t>) const;
[[nodiscard]] bool DoReadPixels(const webgl::ReadPixelsDesc&,
const mozilla::ipc::Shmem&) const;
uvec2 DrawingBufferSize();
// -
@ -1492,6 +1499,12 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
GLenum usage, GLuint srcElemOffset = 0,
GLuint srcElemCountOverride = 0);
void RawBufferData(GLenum target, const uint8_t* srcBytes, size_t srcLen,
GLenum usage);
void RawBufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const uint8_t* srcBytes, size_t srcLen,
bool unsynchronized = false);
void BufferSubData(GLenum target, WebGLsizeiptr dstByteOffset,
const dom::ArrayBufferView& src, GLuint srcElemOffset = 0,
GLuint srcElemCountOverride = 0);
@ -1609,6 +1622,9 @@ class ClientWebGLContext final : public nsICanvasRenderingContextInternal,
GLenum internalFormat, const ivec3& size) const;
// Primitive tex upload functions
void RawTexImage(uint32_t level, GLenum respecFormat, uvec3 offset,
const webgl::PackingInfo& pi,
webgl::TexUnpackBlobDesc&&) const;
void TexImage(uint8_t funcDims, GLenum target, GLint level,
GLenum respecFormat, const ivec3& offset,
const Maybe<ivec3>& size, GLint border,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -15,8 +15,6 @@
#include "mozilla/WeakPtr.h"
#include "mozilla/ThreadLocal.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/layers/LayersTypes.h"
#include <vector>
namespace WGR {
@ -26,18 +24,18 @@ struct PathBuilder;
namespace mozilla {
class WebGLContext;
class WebGLBuffer;
class WebGLFramebuffer;
class WebGLProgram;
class WebGLRenderbuffer;
class WebGLTexture;
class WebGLUniformLocation;
class WebGLVertexArray;
class ClientWebGLContext;
class WebGLBufferJS;
class WebGLFramebufferJS;
class WebGLProgramJS;
class WebGLRenderbufferJS;
class WebGLTextureJS;
class WebGLUniformLocationJS;
class WebGLVertexArrayJS;
namespace gl {
class GLContext;
} // namespace gl
namespace layers {
class SurfaceDescriptor;
}
namespace gfx {
@ -56,275 +54,6 @@ class GlyphCache;
class PathCache;
struct PathVertexRange;
// SharedContextWebgl stores most of the actual WebGL state that may be used by
// any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
// WebGL client context, programs, and buffers for mapping to WebGL.
// Secondarily, it holds shared caches for surfaces, glyphs, paths, and
// shadows so that each DrawTargetWebgl does not require its own cache. It is
// important that SetTarget is called to install the current DrawTargetWebgl
// before actually using the SharedContext, as the individual framebuffers
// and viewport are still maintained in DrawTargetWebgl itself.
class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
public mozilla::SupportsWeakPtr {
friend class DrawTargetWebgl;
friend class SourceSurfaceWebgl;
friend class TextureHandle;
friend class SharedTextureHandle;
friend class StandaloneTexture;
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContextWebgl)
static already_AddRefed<SharedContextWebgl> Create();
~SharedContextWebgl();
gl::GLContext* GetGLContext();
void EnterTlsScope();
void ExitTlsScope();
bool IsContextLost() const;
private:
SharedContextWebgl();
WeakPtr<DrawTargetWebgl> mCurrentTarget;
IntSize mViewportSize;
// The current integer-aligned scissor rect.
IntRect mClipRect;
// The current fractional AA'd clip rect bounds.
Rect mClipAARect;
RefPtr<WebGLContext> mWebgl;
// Avoid spurious state changes by caching last used state.
RefPtr<WebGLProgram> mLastProgram;
RefPtr<WebGLTexture> mLastTexture;
RefPtr<WebGLTexture> mLastClipMask;
// WebGL shader resources
RefPtr<WebGLBuffer> mPathVertexBuffer;
RefPtr<WebGLVertexArray> mPathVertexArray;
// The current insertion offset into the GPU path buffer.
uint32_t mPathVertexOffset = 0;
// The maximum size of the GPU path buffer.
uint32_t mPathVertexCapacity = 0;
// The maximum supported type complexity of a GPU path.
uint32_t mPathMaxComplexity = 0;
// Whether to accelerate stroked paths with AAStroke.
bool mPathAAStroke = true;
// Whether to accelerate stroked paths with WGR.
bool mPathWGRStroke = false;
WGR::PathBuilder* mWGRPathBuilder = nullptr;
// Temporary buffer for generating WGR output into.
UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
RefPtr<WebGLProgram> mSolidProgram;
Maybe<uint32_t> mSolidProgramViewport;
Maybe<uint32_t> mSolidProgramAA;
Maybe<uint32_t> mSolidProgramTransform;
Maybe<uint32_t> mSolidProgramColor;
Maybe<uint32_t> mSolidProgramClipMask;
Maybe<uint32_t> mSolidProgramClipBounds;
RefPtr<WebGLProgram> mImageProgram;
Maybe<uint32_t> mImageProgramViewport;
Maybe<uint32_t> mImageProgramAA;
Maybe<uint32_t> mImageProgramTransform;
Maybe<uint32_t> mImageProgramTexMatrix;
Maybe<uint32_t> mImageProgramTexBounds;
Maybe<uint32_t> mImageProgramColor;
Maybe<uint32_t> mImageProgramSwizzle;
Maybe<uint32_t> mImageProgramSampler;
Maybe<uint32_t> mImageProgramClipMask;
Maybe<uint32_t> mImageProgramClipBounds;
struct SolidProgramUniformState {
Maybe<Array<float, 2>> mViewport;
Maybe<Array<float, 1>> mAA;
Maybe<Array<float, 6>> mTransform;
Maybe<Array<float, 4>> mColor;
Maybe<Array<float, 4>> mClipBounds;
} mSolidProgramUniformState;
struct ImageProgramUniformState {
Maybe<Array<float, 2>> mViewport;
Maybe<Array<float, 1>> mAA;
Maybe<Array<float, 6>> mTransform;
Maybe<Array<float, 6>> mTexMatrix;
Maybe<Array<float, 4>> mTexBounds;
Maybe<Array<float, 4>> mColor;
Maybe<Array<float, 1>> mSwizzle;
Maybe<Array<float, 4>> mClipBounds;
} mImageProgramUniformState;
// Scratch framebuffer used to wrap textures for miscellaneous utility ops.
RefPtr<WebGLFramebuffer> mScratchFramebuffer;
// Buffer filled with zero data for initializing textures.
RefPtr<WebGLBuffer> mZeroBuffer;
size_t mZeroSize = 0;
// 1x1 texture with solid white mask for disabling clipping
RefPtr<WebGLTexture> mNoClipMask;
uint32_t mMaxTextureSize = 0;
bool mRasterizationTruncates = false;
// The current blending operation.
CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
// The constant blend color used for the blending operation.
Maybe<DeviceColor> mLastBlendColor;
// The cached scissor state. Operations that rely on scissor state should
// take care to enable or disable the cached scissor state as necessary.
bool mScissorEnabled = false;
IntRect mLastScissor = {-1, -1, -1, -1};
// A most-recently-used list of allocated texture handles.
LinkedList<RefPtr<TextureHandle>> mTextureHandles;
size_t mNumTextureHandles = 0;
// User data key linking a SourceSurface with its TextureHandle.
UserDataKey mTextureHandleKey = {0};
// User data key linking a SourceSurface with its shadow blur TextureHandle.
UserDataKey mShadowTextureKey = {0};
// User data key linking a ScaledFont with its GlyphCache.
UserDataKey mGlyphCacheKey = {0};
// List of all GlyphCaches currently allocated to fonts.
LinkedList<GlyphCache> mGlyphCaches;
// Cache of rasterized paths.
UniquePtr<PathCache> mPathCache;
// Collection of allocated shared texture pages that may be shared amongst
// many handles.
std::vector<RefPtr<SharedTexture>> mSharedTextures;
// Collection of allocated standalone textures that have a single assigned
// handle.
std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
size_t mUsedTextureMemory = 0;
size_t mTotalTextureMemory = 0;
// The total reserved memory for empty texture pages that are kept around
// for future allocations.
size_t mEmptyTextureMemory = 0;
// A memory pressure event may signal from another thread that caches should
// be cleared if possible.
Atomic<bool> mShouldClearCaches;
// The total number of DrawTargetWebgls using this shared context.
size_t mDrawTargetCount = 0;
// Whether we are inside a scoped usage of TLS MakeCurrent, and what previous
// value to restore it to when exiting the scope.
Maybe<bool> mTlsScope;
bool Initialize();
bool CreateShaders();
void ResetPathVertexBuffer(bool aChanged = true);
void BlendFunc(GLenum aSrcFactor, GLenum aDstFactor);
void SetBlendState(CompositionOp aOp,
const Maybe<DeviceColor>& aColor = Nothing());
void SetClipRect(const Rect& aClipRect);
void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
bool SetClipMask(const RefPtr<WebGLTexture>& aTex);
bool SetNoClipMask();
bool HasClipMask() const {
return mLastClipMask && mLastClipMask != mNoClipMask;
}
Maybe<uint32_t> GetUniformLocation(const RefPtr<WebGLProgram>& prog,
const std::string& aName) const;
template <class T, size_t N>
void UniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
const Array<T, N>& aData);
// Avoids redundant UniformData calls by caching the previously set value.
template <class T, size_t N>
void MaybeUniformData(GLenum aFuncElemType, const Maybe<uint32_t>& aLoc,
const Array<T, N>& aData, Maybe<Array<T, N>>& aCached);
bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
return aDT == mCurrentTarget;
}
bool SetTarget(DrawTargetWebgl* aDT);
// Reset the current target.
void ClearTarget() { mCurrentTarget = nullptr; }
// Reset the last used texture to force binding next use.
void ClearLastTexture(bool aFullClear = false);
bool SupportsPattern(const Pattern& aPattern);
void EnableScissor(const IntRect& aRect);
void DisableScissor();
void SetTexFilter(WebGLTexture* aTex, bool aFilter);
void InitTexParameters(WebGLTexture* aTex, bool aFilter = true);
bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
const IntRect& aBounds, TextureHandle* aHandle = nullptr);
already_AddRefed<DataSourceSurface> ReadSnapshot(
TextureHandle* aHandle = nullptr);
already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
SurfaceFormat aFormat,
RefPtr<WebGLTexture> aTex);
already_AddRefed<TextureHandle> CopySnapshot(
const IntRect& aRect, TextureHandle* aHandle = nullptr);
already_AddRefed<WebGLTexture> GetCompatibleSnapshot(
SourceSurface* aSurface) const;
bool IsCompatibleSurface(SourceSurface* aSurface) const;
bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
const IntRect& aSrcRect, const IntPoint& aDstOffset,
bool aInit, bool aZero = false,
const RefPtr<WebGLTexture>& aTex = nullptr);
already_AddRefed<TextureHandle> AllocateTextureHandle(
SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
bool aRenderable = false);
void DrawQuad();
void DrawTriangles(const PathVertexRange& aRange);
bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions,
Maybe<DeviceColor> aMaskColor = Nothing(),
RefPtr<TextureHandle>* aHandle = nullptr,
bool aTransformed = true, bool aClipped = true,
bool aAccelOnly = false, bool aForceUpdate = false,
const StrokeOptions* aStrokeOptions = nullptr,
const PathVertexRange* aVertexRange = nullptr,
const Matrix* aRectXform = nullptr);
already_AddRefed<TextureHandle> DrawStrokeMask(
const PathVertexRange& aVertexRange, const IntSize& aSize);
bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions = nullptr,
bool aAllowStrokeAlpha = false,
const ShadowOptions* aShadow = nullptr,
bool aCacheable = true,
const Matrix* aPathXform = nullptr);
bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern, const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions,
bool aUseSubpixelAA);
void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
void UnlinkSurfaceTextures();
void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle);
void UnlinkGlyphCaches();
void OnMemoryPressure();
void ClearAllTextures();
void ClearEmptyTextureMemory();
void ClearCachesIfNecessary();
void CachePrefs();
};
// DrawTargetWebgl implements a subset of the DrawTarget API suitable for use
// by CanvasRenderingContext2D. It maps these to a client WebGL context so that
// they can be accelerated where possible by WebGL. It manages both routing to
@ -335,17 +64,20 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
// WebGL context so that data can be more easily interchanged between them and
// also to enable more reasonable limiting of resource usage.
class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
friend class SharedTextureHandle;
friend class StandaloneTexture;
friend class TextureHandle;
friend class SourceSurfaceWebgl;
friend class SharedContextWebgl;
friend class AutoSaveContext;
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetWebgl, override)
private:
IntSize mSize;
RefPtr<WebGLFramebuffer> mFramebuffer;
RefPtr<WebGLTexture> mTex;
RefPtr<WebGLTexture> mClipMask;
RefPtr<WebGLFramebufferJS> mFramebuffer;
RefPtr<WebGLTextureJS> mTex;
RefPtr<WebGLTextureJS> mClipMask;
// The integer-aligned, scissor-compatible conservative bounds of the clip.
IntRect mClipBounds;
// The fractional, AA'd bounds of the clip rect, if applicable.
@ -355,7 +87,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
RefPtr<DrawTargetSkia> mSkiaNoClip;
// The Shmem backing the Skia DT, if applicable.
mozilla::ipc::Shmem mShmem;
mozilla::ipc::IProtocol* mShmemAllocator = nullptr;
// The currently cached snapshot of the WebGL context
RefPtr<DataSourceSurface> mSnapshot;
// Whether the framebuffer is still in the initially clear state.
@ -368,8 +99,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
bool mSkiaLayerClear = false;
// Whether or not the WebGL context has valid contents and is being drawn to
bool mWebglValid = true;
// Whether or not the clip state has changed since last used by
// SharedContextWebgl.
// Whether or not the clip state has changed since last used by SharedContext.
bool mClipChanged = true;
// Whether or not the clip state needs to be refreshed. Sometimes the clip
// state may be overwritten and require a refresh later, even though it has
@ -382,9 +112,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
RefPtr<TextureHandle> mSnapshotTexture;
// Cached unit circle path
RefPtr<Path> mUnitCirclePath;
// Store a log of clips currently pushed so that they can be used to init
// the clip state of temporary DTs.
struct ClipStack {
@ -427,21 +154,269 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
UsageProfile mProfile;
RefPtr<SharedContextWebgl> mSharedContext;
// SharedContext stores most of the actual WebGL state that may be used by
// any number of DrawTargetWebgl's that use it. Foremost, it holds the actual
// WebGL client context, programs, and buffers for mapping to WebGL.
// Secondarily, it holds shared caches for surfaces, glyphs, paths, and
// shadows so that each DrawTargetWebgl does not require its own cache. It is
// important that SetTarget is called to install the current DrawTargetWebgl
// before actually using the SharedContext, as the individual framebuffers
// and viewport are still maintained in DrawTargetWebgl itself.
class SharedContext : public mozilla::RefCounted<SharedContext>,
public mozilla::SupportsWeakPtr {
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedContext)
SharedContext();
~SharedContext();
WeakPtr<DrawTargetWebgl> mCurrentTarget;
IntSize mViewportSize;
// The current integer-aligned scissor rect.
IntRect mClipRect;
// The current fractional AA'd clip rect bounds.
Rect mClipAARect;
RefPtr<ClientWebGLContext> mWebgl;
// Avoid spurious state changes by caching last used state.
RefPtr<WebGLProgramJS> mLastProgram;
RefPtr<WebGLTextureJS> mLastTexture;
RefPtr<WebGLTextureJS> mLastClipMask;
// WebGL shader resources
RefPtr<WebGLBufferJS> mPathVertexBuffer;
RefPtr<WebGLVertexArrayJS> mPathVertexArray;
// The current insertion offset into the GPU path buffer.
uint32_t mPathVertexOffset = 0;
// The maximum size of the GPU path buffer.
uint32_t mPathVertexCapacity = 0;
// The maximum supported type complexity of a GPU path.
uint32_t mPathMaxComplexity = 0;
// Whether to accelerate stroked paths with AAStroke.
bool mPathAAStroke = true;
// Whether to accelerate stroked paths with WGR.
bool mPathWGRStroke = false;
WGR::PathBuilder* mWGRPathBuilder = nullptr;
// Temporary buffer for generating WGR output into.
UniquePtr<WGR::OutputVertex[]> mWGROutputBuffer;
RefPtr<WebGLProgramJS> mSolidProgram;
RefPtr<WebGLUniformLocationJS> mSolidProgramViewport;
RefPtr<WebGLUniformLocationJS> mSolidProgramAA;
RefPtr<WebGLUniformLocationJS> mSolidProgramTransform;
RefPtr<WebGLUniformLocationJS> mSolidProgramColor;
RefPtr<WebGLUniformLocationJS> mSolidProgramClipMask;
RefPtr<WebGLUniformLocationJS> mSolidProgramClipBounds;
RefPtr<WebGLProgramJS> mImageProgram;
RefPtr<WebGLUniformLocationJS> mImageProgramViewport;
RefPtr<WebGLUniformLocationJS> mImageProgramAA;
RefPtr<WebGLUniformLocationJS> mImageProgramTransform;
RefPtr<WebGLUniformLocationJS> mImageProgramTexMatrix;
RefPtr<WebGLUniformLocationJS> mImageProgramTexBounds;
RefPtr<WebGLUniformLocationJS> mImageProgramColor;
RefPtr<WebGLUniformLocationJS> mImageProgramSwizzle;
RefPtr<WebGLUniformLocationJS> mImageProgramSampler;
RefPtr<WebGLUniformLocationJS> mImageProgramClipMask;
RefPtr<WebGLUniformLocationJS> mImageProgramClipBounds;
struct SolidProgramUniformState {
Maybe<Array<float, 2>> mViewport;
Maybe<Array<float, 1>> mAA;
Maybe<Array<float, 6>> mTransform;
Maybe<Array<float, 4>> mColor;
Maybe<Array<float, 4>> mClipBounds;
} mSolidProgramUniformState;
struct ImageProgramUniformState {
Maybe<Array<float, 2>> mViewport;
Maybe<Array<float, 1>> mAA;
Maybe<Array<float, 6>> mTransform;
Maybe<Array<float, 6>> mTexMatrix;
Maybe<Array<float, 4>> mTexBounds;
Maybe<Array<float, 4>> mColor;
Maybe<Array<float, 1>> mSwizzle;
Maybe<Array<float, 4>> mClipBounds;
} mImageProgramUniformState;
// Scratch framebuffer used to wrap textures for miscellaneous utility ops.
RefPtr<WebGLFramebufferJS> mScratchFramebuffer;
// Buffer filled with zero data for initializing textures.
RefPtr<WebGLBufferJS> mZeroBuffer;
size_t mZeroSize = 0;
// 1x1 texture with solid white mask for disabling clipping
RefPtr<WebGLTextureJS> mNoClipMask;
uint32_t mMaxTextureSize = 0;
bool mRasterizationTruncates = false;
// The current blending operation.
CompositionOp mLastCompositionOp = CompositionOp::OP_SOURCE;
// The constant blend color used for the blending operation.
Maybe<DeviceColor> mLastBlendColor;
// The cached scissor state. Operations that rely on scissor state should
// take care to enable or disable the cached scissor state as necessary.
bool mScissorEnabled = false;
IntRect mLastScissor = {-1, -1, -1, -1};
// A most-recently-used list of allocated texture handles.
LinkedList<RefPtr<TextureHandle>> mTextureHandles;
size_t mNumTextureHandles = 0;
// User data key linking a SourceSurface with its TextureHandle.
UserDataKey mTextureHandleKey = {0};
// User data key linking a SourceSurface with its shadow blur TextureHandle.
UserDataKey mShadowTextureKey = {0};
// User data key linking a ScaledFont with its GlyphCache.
UserDataKey mGlyphCacheKey = {0};
// List of all GlyphCaches currently allocated to fonts.
LinkedList<GlyphCache> mGlyphCaches;
// Cache of rasterized paths.
UniquePtr<PathCache> mPathCache;
// Collection of allocated shared texture pages that may be shared amongst
// many handles.
std::vector<RefPtr<SharedTexture>> mSharedTextures;
// Collection of allocated standalone textures that have a single assigned
// handle.
std::vector<RefPtr<StandaloneTexture>> mStandaloneTextures;
size_t mUsedTextureMemory = 0;
size_t mTotalTextureMemory = 0;
// The total reserved memory for empty texture pages that are kept around
// for future allocations.
size_t mEmptyTextureMemory = 0;
// A memory pressure event may signal from another thread that caches should
// be cleared if possible.
Atomic<bool> mShouldClearCaches;
// Whether the Shmem is currently being processed by the remote side. If so,
// we need to wait for processing to complete before any further commands
// modifying the Skia DT can proceed.
bool mWaitForShmem = false;
const Matrix& GetTransform() const { return mCurrentTarget->mTransform; }
bool IsContextLost() const;
bool Initialize();
bool CreateShaders();
void ResetPathVertexBuffer(bool aChanged = true);
void SetBlendState(CompositionOp aOp,
const Maybe<DeviceColor>& aBlendColor = Nothing());
void SetClipRect(const Rect& aClipRect);
void SetClipRect(const IntRect& aClipRect) { SetClipRect(Rect(aClipRect)); }
bool SetClipMask(const RefPtr<WebGLTextureJS>& aTex);
bool SetNoClipMask();
bool HasClipMask() const {
return mLastClipMask && mLastClipMask != mNoClipMask;
}
// Avoids redundant UniformData calls by caching the previously set value.
template <class T, size_t N>
void MaybeUniformData(GLenum aFuncElemType,
const WebGLUniformLocationJS* const aLoc,
const Array<T, N>& aData,
Maybe<Array<T, N>>& aCached);
bool IsCurrentTarget(DrawTargetWebgl* aDT) const {
return aDT == mCurrentTarget;
}
bool SetTarget(DrawTargetWebgl* aDT);
// Reset the current target.
void ClearTarget() { mCurrentTarget = nullptr; }
// Reset the last used texture to force binding next use.
void ClearLastTexture(bool aFullClear = false);
bool SupportsPattern(const Pattern& aPattern);
void EnableScissor(const IntRect& aRect);
void DisableScissor();
void SetTexFilter(WebGLTextureJS* aTex, bool aFilter);
void InitTexParameters(WebGLTextureJS* aTex, bool aFilter = true);
bool ReadInto(uint8_t* aDstData, int32_t aDstStride, SurfaceFormat aFormat,
const IntRect& aBounds, TextureHandle* aHandle = nullptr);
already_AddRefed<DataSourceSurface> ReadSnapshot(
TextureHandle* aHandle = nullptr);
already_AddRefed<TextureHandle> WrapSnapshot(const IntSize& aSize,
SurfaceFormat aFormat,
RefPtr<WebGLTextureJS> aTex);
already_AddRefed<TextureHandle> CopySnapshot(
const IntRect& aRect, TextureHandle* aHandle = nullptr);
already_AddRefed<WebGLTextureJS> GetCompatibleSnapshot(
SourceSurface* aSurface) const;
bool IsCompatibleSurface(SourceSurface* aSurface) const;
bool UploadSurface(DataSourceSurface* aData, SurfaceFormat aFormat,
const IntRect& aSrcRect, const IntPoint& aDstOffset,
bool aInit, bool aZero = false,
const RefPtr<WebGLTextureJS>& aTex = nullptr);
already_AddRefed<TextureHandle> AllocateTextureHandle(
SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
bool aRenderable = false);
bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
const DrawOptions& aOptions,
Maybe<DeviceColor> aMaskColor = Nothing(),
RefPtr<TextureHandle>* aHandle = nullptr,
bool aTransformed = true, bool aClipped = true,
bool aAccelOnly = false, bool aForceUpdate = false,
const StrokeOptions* aStrokeOptions = nullptr,
const PathVertexRange* aVertexRange = nullptr);
already_AddRefed<TextureHandle> DrawStrokeMask(
const PathVertexRange& aVertexRange, const IntSize& aSize);
bool DrawPathAccel(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions = nullptr,
bool aAllowStrokeAlpha = false,
const ShadowOptions* aShadow = nullptr,
bool aCacheable = true);
bool DrawGlyphsAccel(ScaledFont* aFont, const GlyphBuffer& aBuffer,
const Pattern& aPattern, const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions,
bool aUseSubpixelAA);
void PruneTextureHandle(const RefPtr<TextureHandle>& aHandle);
bool PruneTextureMemory(size_t aMargin = 0, bool aPruneUnused = true);
bool RemoveSharedTexture(const RefPtr<SharedTexture>& aTexture);
bool RemoveStandaloneTexture(const RefPtr<StandaloneTexture>& aTexture);
void UnlinkSurfaceTextures();
void UnlinkSurfaceTexture(const RefPtr<TextureHandle>& aHandle);
void UnlinkGlyphCaches();
void OnMemoryPressure();
void ClearAllTextures();
void ClearEmptyTextureMemory();
void ClearCachesIfNecessary();
void WaitForShmem(DrawTargetWebgl* aTarget);
void CachePrefs();
};
RefPtr<SharedContext> mSharedContext;
static MOZ_THREAD_LOCAL(SharedContext*) sSharedContext;
// Try to keep around the shared context for the main thread in case canvases
// are rapidly recreated and destroyed.
static RefPtr<SharedContext> sMainSharedContext;
public:
DrawTargetWebgl();
~DrawTargetWebgl();
static bool CanCreate(const IntSize& aSize, SurfaceFormat aFormat);
static already_AddRefed<DrawTargetWebgl> Create(
const IntSize& aSize, SurfaceFormat aFormat,
ipc::IProtocol* aShmemAllocator,
const RefPtr<SharedContextWebgl>& aSharedContext);
static already_AddRefed<DrawTargetWebgl> Create(const IntSize& aSize,
SurfaceFormat aFormat);
bool Init(const IntSize& aSize, SurfaceFormat aFormat,
ipc::IProtocol* aShmemAllocator,
const RefPtr<SharedContextWebgl>& aSharedContext);
bool Init(const IntSize& aSize, SurfaceFormat aFormat);
bool IsValid() const override;
@ -451,7 +426,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
BackendType GetBackendType() const override { return BackendType::WEBGL; }
IntSize GetSize() const override { return mSize; }
void PrepareData();
already_AddRefed<SourceSurface> GetDataSnapshot();
already_AddRefed<SourceSurface> Snapshot() override;
already_AddRefed<SourceSurface> GetOptimizedSnapshot(DrawTarget* aTarget);
@ -502,12 +476,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
const DrawOptions& aOptions = DrawOptions()) override;
void Fill(const Path* aPath, const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void FillCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
const DrawOptions& aOptions = DrawOptions()) override;
void StrokeCircle(const Point& aOrigin, float aRadius,
const Pattern& aPattern,
const StrokeOptions& aStrokeOptions = StrokeOptions(),
const DrawOptions& aOptions = DrawOptions()) override;
void SetPermitSubpixelAA(bool aPermitSubpixelAA) override;
void FillGlyphs(ScaledFont* aFont, const GlyphBuffer& aBuffer,
@ -564,9 +532,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
void SetTransform(const Matrix& aTransform) override;
void* GetNativeSurface(NativeSurfaceType aType) override;
void CopyToSwapChain(layers::RemoteTextureId aId,
layers::RemoteTextureOwnerId aOwnerId,
base::ProcessId aPid = base::kInvalidProcessId);
Maybe<layers::SurfaceDescriptor> GetFrontBuffer();
void OnMemoryPressure() { mSharedContext->OnMemoryPressure(); }
@ -576,10 +542,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
return stream.str();
}
Maybe<mozilla::ipc::Shmem> GetShmem() const {
return mShmem.IsWritable() ? Some(mShmem) : Nothing();
}
private:
bool SupportsPattern(const Pattern& aPattern) {
return mSharedContext->SupportsPattern(aPattern);
@ -612,9 +574,6 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions = nullptr,
bool aAllowStrokeAlpha = false);
void DrawCircle(const Point& aOrigin, float aRadius, const Pattern& aPattern,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions = nullptr);
bool MarkChanged();
@ -622,7 +581,14 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
void FlattenSkia();
bool FlushFromSkia();
void WaitForShmem() {
if (mSharedContext->mWaitForShmem) {
mSharedContext->WaitForShmem(this);
}
}
void MarkSkiaChanged(bool aOverwrite = false) {
WaitForShmem();
if (aOverwrite) {
mSkiaValid = true;
mSkiaLayer = false;
@ -655,7 +621,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
struct AutoRestoreContext {
DrawTargetWebgl* mTarget;
Rect mClipAARect;
RefPtr<WebGLTexture> mLastClipMask;
RefPtr<WebGLTextureJS> mLastClipMask;
explicit AutoRestoreContext(DrawTargetWebgl* aTarget);

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

@ -137,7 +137,7 @@ class CacheImpl {
class BackingTexture {
public:
BackingTexture(const IntSize& aSize, SurfaceFormat aFormat,
const RefPtr<WebGLTexture>& aTexture);
const RefPtr<WebGLTextureJS>& aTexture);
SurfaceFormat GetFormat() const { return mFormat; }
IntSize GetSize() const { return mSize; }
@ -149,7 +149,7 @@ class BackingTexture {
size_t UsedBytes() const { return UsedBytes(GetFormat(), GetSize()); }
const RefPtr<WebGLTexture>& GetWebGLTexture() const { return mTexture; }
const RefPtr<WebGLTextureJS>& GetWebGLTexture() const { return mTexture; }
bool IsInitialized() const { return mFlags & INITIALIZED; }
void MarkInitialized() { mFlags |= INITIALIZED; }
@ -160,7 +160,7 @@ class BackingTexture {
protected:
IntSize mSize;
SurfaceFormat mFormat;
RefPtr<WebGLTexture> mTexture;
RefPtr<WebGLTextureJS> mTexture;
private:
enum Flags : uint8_t {
@ -195,7 +195,7 @@ class TextureHandle : public RefCounted<TextureHandle>,
virtual void UpdateSize(const IntSize& aSize) {}
virtual void Cleanup(SharedContextWebgl& aContext) {}
virtual void Cleanup(DrawTargetWebgl::SharedContext& aContext) {}
virtual ~TextureHandle() {}
@ -250,7 +250,7 @@ class SharedTexture : public RefCounted<SharedTexture>, public BackingTexture {
MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedTexture)
SharedTexture(const IntSize& aSize, SurfaceFormat aFormat,
const RefPtr<WebGLTexture>& aTexture);
const RefPtr<WebGLTextureJS>& aTexture);
already_AddRefed<SharedTextureHandle> Allocate(const IntSize& aSize);
bool Free(const SharedTextureHandle& aHandle);
@ -280,7 +280,7 @@ class SharedTextureHandle : public TextureHandle {
BackingTexture* GetBackingTexture() override { return mTexture.get(); }
void Cleanup(SharedContextWebgl& aContext) override;
void Cleanup(DrawTargetWebgl::SharedContext& aContext) override;
const RefPtr<SharedTexture>& GetOwner() const { return mTexture; }
@ -297,7 +297,7 @@ class StandaloneTexture : public TextureHandle, public BackingTexture {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(StandaloneTexture, override)
StandaloneTexture(const IntSize& aSize, SurfaceFormat aFormat,
const RefPtr<WebGLTexture>& aTexture);
const RefPtr<WebGLTextureJS>& aTexture);
Type GetType() const override { return Type::STANDALONE; }
@ -315,7 +315,7 @@ class StandaloneTexture : public TextureHandle, public BackingTexture {
void UpdateSize(const IntSize& aSize) override { mSize = aSize; }
void Cleanup(SharedContextWebgl& aContext) override;
void Cleanup(DrawTargetWebgl::SharedContext& aContext) override;
};
// GlyphCacheEntry stores rendering metadata for a rendered text run, as well

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

@ -55,7 +55,7 @@ UniquePtr<HostWebGLContext> HostWebGLContext::Create(
const OwnerData& ownerData, const webgl::InitContextDesc& desc,
webgl::InitContextResult* const out) {
auto host = WrapUnique(new HostWebGLContext(ownerData));
auto webgl = WebGLContext::Create(host.get(), desc, out);
auto webgl = WebGLContext::Create(*host, desc, out);
if (!webgl) return nullptr;
return host;
}

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

@ -17,7 +17,7 @@ SourceSurfaceWebgl::SourceSurfaceWebgl(DrawTargetWebgl* aDT)
SourceSurfaceWebgl::SourceSurfaceWebgl(
const RefPtr<TextureHandle>& aHandle,
const RefPtr<SharedContextWebgl>& aSharedContext)
const RefPtr<DrawTargetWebgl::SharedContext>& aSharedContext)
: mFormat(aHandle->GetFormat()),
mSize(aHandle->GetSize()),
mSharedContext(aSharedContext),
@ -117,7 +117,8 @@ void SourceSurfaceWebgl::GiveTexture(RefPtr<TextureHandle> aHandle) {
// Handler for when the owner DrawTargetWebgl is destroying the cached texture
// handle that has been allocated for this snapshot.
void SourceSurfaceWebgl::OnUnlinkTexture(SharedContextWebgl* aContext) {
void SourceSurfaceWebgl::OnUnlinkTexture(
DrawTargetWebgl::SharedContext* aContext) {
// If we get here, then we must have copied a snapshot, which only happens
// if the target changed.
MOZ_ASSERT(!mDT);
@ -141,7 +142,7 @@ already_AddRefed<SourceSurface> SourceSurfaceWebgl::ExtractSubrect(
return nullptr;
}
RefPtr<TextureHandle> subHandle;
RefPtr<SharedContextWebgl> sharedContext;
RefPtr<DrawTargetWebgl::SharedContext> sharedContext;
if (mDT) {
// If this is still a snapshot linked to a target, then copy from the
// target.

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

@ -13,7 +13,6 @@
namespace mozilla::gfx {
class DrawTargetWebgl;
class SharedContextWebgl;
class TextureHandle;
// SourceSurfaceWebgl holds WebGL resources that can be used to efficiently
@ -24,8 +23,9 @@ class SourceSurfaceWebgl : public DataSourceSurface {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceWebgl, override)
explicit SourceSurfaceWebgl(DrawTargetWebgl* aDT);
SourceSurfaceWebgl(const RefPtr<TextureHandle>& aHandle,
const RefPtr<SharedContextWebgl>& aSharedContext);
SourceSurfaceWebgl(
const RefPtr<TextureHandle>& aHandle,
const RefPtr<typename DrawTargetWebgl::SharedContext>& aSharedContext);
virtual ~SourceSurfaceWebgl();
SurfaceType GetType() const override { return SurfaceType::WEBGL; }
@ -44,7 +44,6 @@ class SourceSurfaceWebgl : public DataSourceSurface {
private:
friend class DrawTargetWebgl;
friend class SharedContextWebgl;
bool EnsureData();
@ -52,7 +51,7 @@ class SourceSurfaceWebgl : public DataSourceSurface {
void GiveTexture(RefPtr<TextureHandle> aHandle);
void OnUnlinkTexture(SharedContextWebgl* aContext);
void OnUnlinkTexture(typename DrawTargetWebgl::SharedContext* aContext);
DrawTargetWebgl* GetTarget() const { return mDT.get(); }
@ -63,7 +62,7 @@ class SourceSurfaceWebgl : public DataSourceSurface {
// The draw target that currently owns the texture for this surface.
WeakPtr<DrawTargetWebgl> mDT;
// The actual shared context that any WebGL resources belong to.
WeakPtr<SharedContextWebgl> mSharedContext;
WeakPtr<typename DrawTargetWebgl::SharedContext> mSharedContext;
// If this snapshot has been copied into a cached texture handle.
RefPtr<TextureHandle> mHandle;
};

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

@ -25,7 +25,7 @@ class WebGL2Context final : public WebGLContext {
friend class WebGLContext;
public:
WebGL2Context(HostWebGLContext* host, const webgl::InitContextDesc& desc)
WebGL2Context(HostWebGLContext& host, const webgl::InitContextDesc& desc)
: WebGLContext(host, desc) {}
virtual bool IsWebGL2() const override { return true; }

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

@ -136,18 +136,16 @@ bool WebGLContext::LruPosition::IsInsertedLocked() const {
return mItr != sLru.end();
}
WebGLContext::WebGLContext(HostWebGLContext* host,
WebGLContext::WebGLContext(HostWebGLContext& host,
const webgl::InitContextDesc& desc)
: gl(mGL_OnlyClearInDestroyResourcesAndContext), // const reference
mHost(host),
mHost(&host),
mResistFingerprinting(desc.resistFingerprinting),
mOptions(desc.options),
mPrincipalKey(desc.principalKey),
mContextLossHandler(this),
mRequestedSize(desc.size) {
if (host) {
host->mContext = this;
}
host.mContext = this;
const FuncScope funcScope(*this, "<Create>");
}
@ -514,7 +512,7 @@ UniquePtr<webgl::FormatUsageAuthority> WebGLContext::CreateFormatUsage(
}
/*static*/
RefPtr<WebGLContext> WebGLContext::Create(HostWebGLContext* host,
RefPtr<WebGLContext> WebGLContext::Create(HostWebGLContext& host,
const webgl::InitContextDesc& desc,
webgl::InitContextResult* const out) {
AUTO_PROFILER_LABEL("WebGLContext::Create", GRAPHICS);
@ -741,7 +739,7 @@ void WebGLContext::LoseLruContextIfLimitExceeded() {
"Exceeded %u live WebGL contexts for this principal, losing the "
"least recently used one.",
maxContextsPerPrincipal);
JsWarning(ToString(text));
mHost->JsWarning(ToString(text));
for (const auto& context : sLru) {
if (context->mPrincipalKey == mPrincipalKey) {
@ -760,7 +758,7 @@ void WebGLContext::LoseLruContextIfLimitExceeded() {
"Exceeded %u live WebGL contexts, losing the least "
"recently used one.",
maxContexts);
JsWarning(ToString(text));
mHost->JsWarning(ToString(text));
const auto& context = sLru.front();
MOZ_ASSERT(context != this);
@ -1052,8 +1050,7 @@ void WebGLContext::Present(WebGLFramebuffer* const xrFb,
void WebGLContext::CopyToSwapChain(WebGLFramebuffer* const srcFb,
const layers::TextureType consumerType,
const webgl::SwapChainOptions& options,
base::ProcessId pid) {
const webgl::SwapChainOptions& options) {
const FuncScope funcScope(*this, "<CopyToSwapChain>");
if (IsContextLost()) return;
@ -1076,7 +1073,7 @@ void WebGLContext::CopyToSwapChain(WebGLFramebuffer* const srcFb,
// read back the WebGL framebuffer into and push it as a remote texture.
if (useAsync && srcFb->mSwapChain.mFactory->GetConsumerType() ==
layers::TextureType::Unknown) {
PushRemoteTexture(srcFb, srcFb->mSwapChain, nullptr, options, pid);
PushRemoteTexture(srcFb, srcFb->mSwapChain, nullptr, options);
return;
}
@ -1100,15 +1097,14 @@ void WebGLContext::CopyToSwapChain(WebGLFramebuffer* const srcFb,
if (useAsync) {
PushRemoteTexture(srcFb, srcFb->mSwapChain, srcFb->mSwapChain.FrontBuffer(),
options, pid);
options);
}
}
bool WebGLContext::PushRemoteTexture(WebGLFramebuffer* fb,
gl::SwapChain& swapChain,
std::shared_ptr<gl::SharedSurface> surf,
const webgl::SwapChainOptions& options,
base::ProcessId pid) {
const webgl::SwapChainOptions& options) {
const auto onFailure = [&]() -> bool {
GenerateWarning("Remote texture creation failed.");
LoseContext();
@ -1122,12 +1118,11 @@ bool WebGLContext::PushRemoteTexture(WebGLFramebuffer* fb,
if (!mRemoteTextureOwner) {
// Ensure we have a remote texture owner client for WebGLParent.
const auto* outOfProcess = mHost ? mHost->mOwnerData.outOfProcess : nullptr;
if (outOfProcess) {
pid = outOfProcess->OtherPid();
} else if (pid == base::kInvalidProcessId) {
if (!outOfProcess) {
return onFailure();
}
mRemoteTextureOwner = MakeRefPtr<layers::RemoteTextureOwnerClient>(pid);
mRemoteTextureOwner =
MakeRefPtr<layers::RemoteTextureOwnerClient>(outOfProcess->OtherPid());
}
layers::RemoteTextureOwnerId ownerId = options.remoteTextureOwnerId;
@ -1476,9 +1471,7 @@ void WebGLContext::CheckForContextLoss() {
void WebGLContext::HandlePendingContextLoss() {
mIsContextLost = true;
if (mHost) {
mHost->OnContextLoss(mPendingContextLossReason);
}
mHost->OnContextLoss(mPendingContextLossReason);
}
void WebGLContext::LoseContextLruLocked(const webgl::ContextLossReason reason) {
@ -1883,17 +1876,6 @@ nsresult webgl::AvailabilityRunnable::Run() {
// -
void WebGLContext::JsWarning(const std::string& text) const {
if (mHost) {
mHost->JsWarning(text);
}
#ifdef DEBUG
if (!mHost) {
NS_WARNING(text.c_str());
}
#endif
}
void WebGLContext::GenerateErrorImpl(const GLenum errOrWarning,
const std::string& text) const {
auto err = errOrWarning;
@ -1939,9 +1921,9 @@ void WebGLContext::GenerateErrorImpl(const GLenum errOrWarning,
if (isPerfWarning) {
const auto perfText = std::string("WebGL perf warning: ") + text;
JsWarning(perfText);
mHost->JsWarning(perfText);
} else {
JsWarning(text);
mHost->JsWarning(text);
}
*pNumWarnings += 1;
@ -1950,7 +1932,7 @@ void WebGLContext::GenerateErrorImpl(const GLenum errOrWarning,
"After reporting %i, no further %s will be reported for this WebGL "
"context.",
int(*pNumWarnings), warningsType);
JsWarning(ToString(msg));
mHost->JsWarning(ToString(msg));
}
}

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

@ -311,7 +311,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
mutable FuncScope* mFuncScope = nullptr;
public:
static RefPtr<WebGLContext> Create(HostWebGLContext*,
static RefPtr<WebGLContext> Create(HostWebGLContext&,
const webgl::InitContextDesc&,
webgl::InitContextResult* out);
@ -319,7 +319,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
void FinishInit();
protected:
WebGLContext(HostWebGLContext*, const webgl::InitContextDesc&);
WebGLContext(HostWebGLContext&, const webgl::InitContextDesc&);
virtual ~WebGLContext();
RefPtr<layers::CompositableHost> mCompositableHost;
@ -451,8 +451,6 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
static const char* ErrorName(GLenum error);
void JsWarning(const std::string& text) const;
/**
* Return displayable name for GLenum.
* This version is like gl::GLenumToStr but with out the GL_ prefix to
@ -497,8 +495,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
// without need to set the preserveDrawingBuffer option.
void CopyToSwapChain(
WebGLFramebuffer*, layers::TextureType,
const webgl::SwapChainOptions& options = webgl::SwapChainOptions(),
base::ProcessId pid = base::kInvalidProcessId);
const webgl::SwapChainOptions& options = webgl::SwapChainOptions());
// In use cases where a framebuffer is used as an offscreen framebuffer and
// does not need to be committed to the swap chain, it may still be useful
// for the implementation to delineate distinct frames, such as when sharing
@ -1259,8 +1256,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
bool PushRemoteTexture(WebGLFramebuffer*, gl::SwapChain&,
std::shared_ptr<gl::SharedSurface>,
const webgl::SwapChainOptions& options,
base::ProcessId pid = base::kInvalidProcessId);
const webgl::SwapChainOptions& options);
// --

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

@ -238,7 +238,7 @@ fuzzy(0-1,0-2) skip-if(cocoaWidget||winWidget||gtkWidget) needs-focus == drawFoc
# Check that captureStream() displays in a local video element
== capturestream.html wrapper.html?green.png
fuzzy(0-235,0-3104) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
fuzzy-if(azureSkia,0-16,0-20) fuzzy-if(Android,0-3,0-40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),0-1,0-1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
# Bug 1366027
== clipped-dash-stroke-rect.html clipped-dash-stroke-rect-ref.html

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

@ -700,16 +700,6 @@ class SourceSurface : public SupportsThreadSafeWeakPtr<SourceSurface> {
return surface.forget();
}
/**
* Attempts to read the contents of this surface into a destination data
* surface. This may simply return false to signal that this operation is
* not supported or is not efficient, in which case the caller should try
* to convert this surface to a data surface to read from it instead.
*/
virtual bool ReadInto(DataSourceSurface* aSurface, const IntRect& aRect) {
return false;
}
/** Tries to get this SourceSurface's native surface. This will fail if aType
* is not the type of this SourceSurface's native surface.
*/

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

@ -393,17 +393,6 @@ void DrawTargetRecording::Stroke(const Path* aPath, const Pattern& aPattern,
RecordedStroke(this, pathRecording, aPattern, aStrokeOptions, aOptions));
}
void DrawTargetRecording::DrawShadow(const Path* aPath, const Pattern& aPattern,
const ShadowOptions& aShadow,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions) {
RefPtr<PathRecording> pathRecording = EnsurePathStored(aPath);
EnsurePatternDependenciesStored(aPattern);
mRecorder->RecordEvent(RecordedDrawShadow(this, pathRecording, aPattern,
aShadow, aOptions, aStrokeOptions));
}
already_AddRefed<SourceSurface> DrawTargetRecording::Snapshot() {
RefPtr<SourceSurface> retSurf =
new SourceSurfaceRecording(mRect.Size(), mFormat, mRecorder);

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

@ -73,11 +73,6 @@ class DrawTargetRecording : public DrawTarget {
const ShadowOptions& aShadow,
CompositionOp aOperator) override;
virtual void DrawShadow(const Path* aPath, const Pattern& aPattern,
const ShadowOptions& aShadow,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions) override;
/*
* Clear a rectangle on the draw target to transparent black. This will
* respect the clipping region and transform.

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

@ -376,7 +376,6 @@ class RecordedEvent {
DRAWSURFACE,
DRAWDEPENDENTSURFACE,
DRAWSURFACEWITHSHADOW,
DRAWSHADOW,
PATHCREATION,
PATHDESTRUCTION,
SOURCESURFACECREATION,

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

@ -824,44 +824,6 @@ class RecordedDrawSurfaceWithShadow
CompositionOp mOp;
};
class RecordedDrawShadow : public RecordedDrawingEvent<RecordedDrawShadow> {
public:
RecordedDrawShadow(DrawTarget* aDT, ReferencePtr aPath,
const Pattern& aPattern, const ShadowOptions& aShadow,
const DrawOptions& aOptions,
const StrokeOptions* aStrokeOptions)
: RecordedDrawingEvent(DRAWSHADOW, aDT),
mPath(aPath),
mPattern(),
mShadow(aShadow),
mOptions(aOptions),
mHasStrokeOptions(!!aStrokeOptions),
mStrokeOptions(aStrokeOptions ? *aStrokeOptions : StrokeOptions()) {
StorePattern(mPattern, aPattern);
}
bool PlayEvent(Translator* aTranslator) const override;
template <class S>
void Record(S& aStream) const;
void OutputSimpleEventInfo(std::stringstream& aStringStream) const override;
std::string GetName() const override { return "DrawShadow"; }
private:
friend class RecordedEvent;
template <class S>
MOZ_IMPLICIT RecordedDrawShadow(S& aStream);
ReferencePtr mPath;
PatternStorage mPattern;
ShadowOptions mShadow;
DrawOptions mOptions;
bool mHasStrokeOptions;
StrokeOptions mStrokeOptions;
};
class RecordedDrawFilter : public RecordedDrawingEvent<RecordedDrawFilter> {
public:
RecordedDrawFilter(DrawTarget* aDT, ReferencePtr aNode,
@ -3136,55 +3098,6 @@ inline void RecordedDrawSurfaceWithShadow::OutputSimpleEventInfo(
<< mShadow.mColor.a << ")";
}
inline bool RecordedDrawShadow::PlayEvent(Translator* aTranslator) const {
DrawTarget* dt = aTranslator->LookupDrawTarget(mDT);
if (!dt) {
return false;
}
Path* path = aTranslator->LookupPath(mPath);
if (!path) {
return false;
}
dt->DrawShadow(path, *GenericPattern(mPattern, aTranslator), mShadow,
mOptions, mHasStrokeOptions ? &mStrokeOptions : nullptr);
return true;
}
template <class S>
void RecordedDrawShadow::Record(S& aStream) const {
RecordedDrawingEvent::Record(aStream);
WriteElement(aStream, mPath);
RecordPatternData(aStream, mPattern);
WriteElement(aStream, mShadow);
WriteElement(aStream, mOptions);
WriteElement(aStream, mHasStrokeOptions);
if (mHasStrokeOptions) {
RecordStrokeOptions(aStream, mStrokeOptions);
}
}
template <class S>
RecordedDrawShadow::RecordedDrawShadow(S& aStream)
: RecordedDrawingEvent(DRAWSHADOW, aStream) {
ReadElement(aStream, mPath);
ReadPatternData(aStream, mPattern);
ReadElement(aStream, mShadow);
ReadDrawOptions(aStream, mOptions);
ReadElement(aStream, mHasStrokeOptions);
if (mHasStrokeOptions) {
ReadStrokeOptions(aStream, mStrokeOptions);
}
}
inline void RecordedDrawShadow::OutputSimpleEventInfo(
std::stringstream& aStringStream) const {
aStringStream << "[" << mDT << "] DrawShadow (" << mPath << ") DeviceColor: ("
<< mShadow.mColor.r << ", " << mShadow.mColor.g << ", "
<< mShadow.mColor.b << ", " << mShadow.mColor.a << ")";
}
inline RecordedPathCreation::RecordedPathCreation(PathRecording* aPath)
: RecordedEventDerived(PATHCREATION),
mRefPtr(aPath),
@ -4241,7 +4154,6 @@ inline void RecordedDestination::OutputSimpleEventInfo(
f(DRAWSURFACE, RecordedDrawSurface); \
f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \
f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \
f(DRAWSHADOW, RecordedDrawShadow); \
f(DRAWFILTER, RecordedDrawFilter); \
f(PATHCREATION, RecordedPathCreation); \
f(PATHDESTRUCTION, RecordedPathDestruction); \

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

@ -308,13 +308,6 @@ GLContext::~GLContext() {
}
}
/*static*/
void GLContext::InvalidateCurrentContext() {
if (sCurrentContext.init()) {
sCurrentContext.set(nullptr);
}
}
/*static*/
void GLContext::StaticDebugCallback(GLenum source, GLenum type, GLuint id,
GLenum severity, GLsizei length,
@ -2408,7 +2401,7 @@ bool GLContext::MakeCurrent(bool aForce) const {
}
if (MOZ_LIKELY(isCurrent)) {
MOZ_ASSERT(IsCurrentImpl() ||
MakeCurrentImpl()); // Might have lost context.
!MakeCurrentImpl()); // Might have lost context.
return true;
}
}

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

@ -180,8 +180,6 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
public:
static MOZ_THREAD_LOCAL(const GLContext*) sCurrentContext;
static void InvalidateCurrentContext();
const GLContextDesc mDesc;
bool mImplicitMakeCurrent = false;
@ -192,12 +190,9 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr {
const bool mWasTlsOk;
public:
explicit TlsScope(GLContext* const gl, bool invalidate = false)
explicit TlsScope(GLContext* const gl)
: mGL(gl), mWasTlsOk(gl && gl->mUseTLSIsCurrent) {
if (mGL) {
if (invalidate) {
InvalidateCurrentContext();
}
mGL->mUseTLSIsCurrent = true;
}
}

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

@ -159,13 +159,7 @@ void CanvasManagerChild::DeactivateCanvas() {
}
}
void CanvasManagerChild::BlockCanvas() { mBlocked = true; }
RefPtr<layers::CanvasChild> CanvasManagerChild::GetCanvasChild() {
if (mBlocked) {
return nullptr;
}
if (!mActive) {
MOZ_ASSERT(!mCanvasChild);
return nullptr;

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

@ -48,7 +48,6 @@ class CanvasManagerChild final : public PCanvasManagerChild {
bool IsCanvasActive() { return mActive; }
void EndCanvasTransaction();
void DeactivateCanvas();
void BlockCanvas();
RefPtr<layers::CanvasChild> GetCanvasChild();
@ -63,7 +62,6 @@ class CanvasManagerChild final : public PCanvasManagerChild {
RefPtr<webgpu::WebGPUChild> mWebGPUChild;
const uint32_t mId;
bool mActive = true;
bool mBlocked = false;
static MOZ_THREAD_LOCAL(CanvasManagerChild*) sLocalManager;
static Atomic<uint32_t> sNextId;

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

@ -360,15 +360,14 @@ mozilla::ipc::IPCResult GPUParent::RecvInit(
// here that would normally be initialized there.
SkGraphics::Init();
bool useRemoteCanvas =
gfxVars::RemoteCanvasEnabled() || gfxVars::UseAcceleratedCanvas2D();
if (useRemoteCanvas) {
if (gfxVars::RemoteCanvasEnabled()) {
gfxGradientCache::Init();
}
#if defined(XP_WIN)
if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
if (DeviceManagerDx::Get()->CreateCompositorDevices() && useRemoteCanvas) {
if (DeviceManagerDx::Get()->CreateCompositorDevices() &&
gfxVars::RemoteCanvasEnabled()) {
if (DeviceManagerDx::Get()->CreateCanvasDevice()) {
gfxDWriteFont::InitDWriteSupport();
} else {

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

@ -423,7 +423,6 @@ void CanvasEventRingBuffer::CheckAndSignalWriter() {
do {
switch (mWrite->state) {
case State::Processing:
case State::Failed:
return;
case State::AboutToWait:
// The writer is making a decision about whether to wait. So, we must
@ -499,7 +498,7 @@ uint32_t CanvasEventRingBuffer::WaitForBytesToRead() {
return mWrite->count - mOurCount;
}
void CanvasEventRingBuffer::ReturnWrite(const uint8_t* aData, size_t aSize) {
void CanvasEventRingBuffer::ReturnWrite(const char* aData, size_t aSize) {
uint32_t writeCount = mRead->returnCount;
uint32_t bufPos = writeCount % StreamSize();
uint32_t bufRemaining = StreamSize() - bufPos;
@ -527,13 +526,7 @@ void CanvasEventRingBuffer::ReturnWrite(const uint8_t* aData, size_t aSize) {
mRead->returnCount = writeCount;
}
void CanvasEventRingBuffer::ReturnRead(uint8_t* aOut, const gfx::IntSize& aSize,
size_t aBPP, size_t aStride) {
if (aSize.IsEmpty()) {
return;
}
aStride = std::max(aStride, aBPP * size_t(aSize.width));
void CanvasEventRingBuffer::ReturnRead(char* aOut, size_t aSize) {
// First wait for the event returning the data to be read.
WaitForCheckpoint(mOurCount);
uint32_t readCount = mWrite->returnCount;
@ -549,28 +542,29 @@ void CanvasEventRingBuffer::ReturnRead(uint8_t* aOut, const gfx::IntSize& aSize,
}
}
uint8_t* outRow = aOut;
for (int32_t row = 0; row < aSize.height; row++) {
uint8_t* outPos = outRow;
uint32_t remainingRow = aSize.width * aBPP;
while (remainingRow > 0) {
uint32_t bufPos = readCount % StreamSize();
uint32_t bufRemaining = StreamSize() - bufPos;
uint32_t availableToRead =
std::min(bufRemaining, (mRead->returnCount - readCount));
if (availableToRead > 0) {
uint32_t availableRow = std::min(availableToRead, remainingRow);
memcpy(outPos, mBuf + bufPos, availableRow);
readCount += availableRow;
mWrite->returnCount = readCount;
outPos += availableRow;
remainingRow -= availableRow;
} else if (mWriterServices->ReaderClosed()) {
return;
}
uint32_t bufPos = readCount % StreamSize();
uint32_t bufRemaining = StreamSize() - bufPos;
uint32_t availableToRead =
std::min(bufRemaining, (mRead->returnCount - readCount));
while (availableToRead < aSize) {
if (availableToRead) {
memcpy(aOut, mBuf + bufPos, availableToRead);
readCount += availableToRead;
mWrite->returnCount = readCount;
bufPos = readCount % StreamSize();
bufRemaining = StreamSize() - bufPos;
aOut += availableToRead;
aSize -= availableToRead;
} else if (mWriterServices->ReaderClosed()) {
return;
}
outRow += aStride;
availableToRead = std::min(bufRemaining, (mRead->returnCount - readCount));
}
memcpy(aOut, mBuf + bufPos, aSize);
readCount += aSize;
mWrite->returnCount = readCount;
}
void CanvasDrawEventRecorder::StoreSourceSurfaceRecording(

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

@ -177,7 +177,7 @@ class CanvasEventRingBuffer final : public gfx::EventRingBuffer {
* @param aData the data to be written back to the writer
* @param aSize the number of chars to write
*/
void ReturnWrite(const uint8_t* aData, size_t aSize);
void ReturnWrite(const char* aData, size_t aSize);
/**
* Used to read data sent back from the reader via ReturnWrite. This is done
@ -187,11 +187,7 @@ class CanvasEventRingBuffer final : public gfx::EventRingBuffer {
* @param aOut the pointer to read into
* @param aSize the number of chars to read
*/
void ReturnRead(uint8_t* aOut, const gfx::IntSize& aSize, size_t aBPP,
size_t aStride = 0);
void ReturnRead(uint8_t* aOut, size_t aSize) {
ReturnRead(aOut, gfx::IntSize(aSize, 1), 1);
}
void ReturnRead(char* aOut, size_t aSize);
bool UsingLargeStream() { return mLargeStream; }
@ -294,12 +290,7 @@ class CanvasDrawEventRecorder final : public gfx::DrawEventRecorderPrivate {
void Flush() final {}
void ReturnRead(uint8_t* aOut, const gfx::IntSize& aSize, size_t aBPP,
size_t aStride = 0) {
mOutputStream.ReturnRead(aOut, aSize, aBPP, aStride);
}
void ReturnRead(uint8_t* aOut, size_t aSize) {
void ReturnRead(char* aOut, size_t aSize) {
mOutputStream.ReturnRead(aOut, aSize);
}

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

@ -6,7 +6,6 @@
#include "PersistentBufferProvider.h"
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/TextureForwarder.h"
#include "mozilla/gfx/gfxVars.h"
@ -97,148 +96,65 @@ PersistentBufferProviderBasic::Create(gfx::IntSize aSize,
return provider.forget();
}
static already_AddRefed<TextureClient> CreateTexture(
KnowsCompositor* aKnowsCompositor, gfx::SurfaceFormat aFormat,
gfx::IntSize aSize, bool aWillReadFrequently = false,
Maybe<RemoteTextureOwnerId> aRemoteTextureOwnerId = {}) {
TextureAllocationFlags flags = ALLOC_DEFAULT;
if (aWillReadFrequently) {
flags = TextureAllocationFlags(flags | ALLOC_DO_NOT_ACCELERATE);
}
if (aRemoteTextureOwnerId) {
flags = TextureAllocationFlags(flags | ALLOC_FORCE_REMOTE);
}
RefPtr<TextureClient> tc = TextureClient::CreateForDrawing(
aKnowsCompositor, aFormat, aSize, BackendSelector::Canvas,
TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK, flags);
if (tc && aRemoteTextureOwnerId) {
if (TextureData* td = tc->GetInternalData()) {
td->SetRemoteTextureOwnerId(*aRemoteTextureOwnerId);
}
}
return tc.forget();
}
// static
already_AddRefed<PersistentBufferProviderAccelerated>
PersistentBufferProviderAccelerated::Create(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
KnowsCompositor* aKnowsCompositor) {
if (!DrawTargetWebgl::CanCreate(aSize, aFormat)) {
return nullptr;
}
if (!aKnowsCompositor || !aKnowsCompositor->GetTextureForwarder() ||
!aKnowsCompositor->GetTextureForwarder()->IPCOpen()) {
return nullptr;
}
auto remoteTextureOwnerId = RemoteTextureOwnerId::GetNext();
RefPtr<TextureClient> texture = CreateTexture(
aKnowsCompositor, aFormat, aSize, false, Some(remoteTextureOwnerId));
if (!texture) {
return nullptr;
}
RefPtr<PersistentBufferProviderAccelerated> provider =
new PersistentBufferProviderAccelerated(texture);
return provider.forget();
}
PersistentBufferProviderAccelerated::PersistentBufferProviderAccelerated(
const RefPtr<TextureClient>& aTexture)
: mTexture(aTexture) {
DrawTarget* aDt)
: PersistentBufferProviderBasic(aDt) {
MOZ_COUNT_CTOR(PersistentBufferProviderAccelerated);
MOZ_ASSERT(aDt->GetBackendType() == BackendType::WEBGL);
}
PersistentBufferProviderAccelerated::~PersistentBufferProviderAccelerated() {
MOZ_COUNT_DTOR(PersistentBufferProviderAccelerated);
Destroy();
}
void PersistentBufferProviderAccelerated::Destroy() {
mSnapshot = nullptr;
mDrawTarget = nullptr;
inline gfx::DrawTargetWebgl*
PersistentBufferProviderAccelerated::GetDrawTargetWebgl() const {
return static_cast<gfx::DrawTargetWebgl*>(mDrawTarget.get());
}
if (mTexture) {
if (mTexture->IsLocked()) {
MOZ_ASSERT(false);
mTexture->Unlock();
}
mTexture = nullptr;
}
Maybe<layers::SurfaceDescriptor>
PersistentBufferProviderAccelerated::GetFrontBuffer() {
return GetDrawTargetWebgl()->GetFrontBuffer();
}
already_AddRefed<gfx::DrawTarget>
PersistentBufferProviderAccelerated::BorrowDrawTarget(
const gfx::IntRect& aPersistedRect) {
if (!mDrawTarget) {
if (!mTexture->Lock(OpenMode::OPEN_READ_WRITE)) {
return nullptr;
}
mDrawTarget = mTexture->BorrowDrawTarget();
if (mDrawTarget) {
mDrawTarget->ClearRect(Rect(0, 0, 0, 0));
if (!mDrawTarget->IsValid()) {
mDrawTarget = nullptr;
}
}
}
return do_AddRef(mDrawTarget);
GetDrawTargetWebgl()->BeginFrame(aPersistedRect);
return PersistentBufferProviderBasic::BorrowDrawTarget(aPersistedRect);
}
bool PersistentBufferProviderAccelerated::ReturnDrawTarget(
already_AddRefed<gfx::DrawTarget> aDT) {
{
RefPtr<gfx::DrawTarget> dt(aDT);
MOZ_ASSERT(mDrawTarget == dt);
if (!mDrawTarget) {
return false;
}
mDrawTarget = nullptr;
}
mTexture->Unlock();
return true;
bool result = PersistentBufferProviderBasic::ReturnDrawTarget(std::move(aDT));
GetDrawTargetWebgl()->EndFrame();
return result;
}
already_AddRefed<gfx::SourceSurface>
PersistentBufferProviderAccelerated::BorrowSnapshot(gfx::DrawTarget* aTarget) {
if (mDrawTarget) {
MOZ_ASSERT(mTexture->IsLocked());
} else {
if (mTexture->IsLocked()) {
MOZ_ASSERT(false);
return nullptr;
}
if (!mTexture->Lock(OpenMode::OPEN_READ)) {
return nullptr;
}
}
mSnapshot = mTexture->BorrowSnapshot();
mSnapshot = GetDrawTargetWebgl()->GetOptimizedSnapshot(aTarget);
return do_AddRef(mSnapshot);
}
void PersistentBufferProviderAccelerated::ReturnSnapshot(
already_AddRefed<gfx::SourceSurface> aSnapshot) {
RefPtr<SourceSurface> snapshot = aSnapshot;
MOZ_ASSERT(!snapshot || snapshot == mSnapshot);
mSnapshot = nullptr;
if (!mDrawTarget) {
mTexture->Unlock();
}
}
Maybe<SurfaceDescriptor> PersistentBufferProviderAccelerated::GetFrontBuffer() {
SurfaceDescriptor desc;
if (mTexture->GetInternalData()->Serialize(desc)) {
return Some(desc);
}
return Nothing();
}
bool PersistentBufferProviderAccelerated::RequiresRefresh() const {
return mTexture->GetInternalData()->RequiresRefresh();
return GetDrawTargetWebgl()->RequiresRefresh();
}
void PersistentBufferProviderAccelerated::OnMemoryPressure() {
GetDrawTargetWebgl()->OnMemoryPressure();
}
static already_AddRefed<TextureClient> CreateTexture(
KnowsCompositor* aKnowsCompositor, gfx::SurfaceFormat aFormat,
gfx::IntSize aSize, bool aWillReadFrequently) {
TextureAllocationFlags flags = ALLOC_DEFAULT;
if (aWillReadFrequently) {
flags = TextureAllocationFlags(flags | ALLOC_DO_NOT_ACCELERATE);
}
return TextureClient::CreateForDrawing(
aKnowsCompositor, aFormat, aSize, BackendSelector::Canvas,
TextureFlags::DEFAULT | TextureFlags::NON_BLOCKING_READ_LOCK, flags);
}
// static
@ -282,6 +198,7 @@ PersistentBufferProviderShared::PersistentBufferProviderShared(
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
KnowsCompositor* aKnowsCompositor, RefPtr<TextureClient>& aTexture,
bool aWillReadFrequently)
: mSize(aSize),
mFormat(aFormat),
mKnowsCompositor(aKnowsCompositor),

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

@ -24,11 +24,11 @@ class ClientWebGLContext;
namespace gfx {
class SourceSurface;
class DrawTarget;
class DrawTargetWebgl;
} // namespace gfx
namespace layers {
struct RemoteTextureOwnerId;
class TextureClient;
/**
@ -104,7 +104,12 @@ class PersistentBufferProvider : public RefCounted<PersistentBufferProvider>,
*/
virtual bool RequiresRefresh() const { return false; }
virtual Maybe<SurfaceDescriptor> GetFrontBuffer() { return Nothing(); }
/**
* Provide a WebGL front buffer for compositing, if available.
*/
virtual Maybe<layers::SurfaceDescriptor> GetFrontBuffer() {
return Nothing();
}
};
class PersistentBufferProviderBasic : public PersistentBufferProvider {
@ -141,17 +146,18 @@ class PersistentBufferProviderBasic : public PersistentBufferProvider {
RefPtr<gfx::SourceSurface> mSnapshot;
};
class PersistentBufferProviderAccelerated : public PersistentBufferProvider {
class PersistentBufferProviderAccelerated
: public PersistentBufferProviderBasic {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PersistentBufferProviderAccelerated,
override)
static already_AddRefed<PersistentBufferProviderAccelerated> Create(
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
KnowsCompositor* aKnowsCompositor);
explicit PersistentBufferProviderAccelerated(gfx::DrawTarget* aTarget);
bool IsAccelerated() const override { return true; }
Maybe<layers::SurfaceDescriptor> GetFrontBuffer() override;
already_AddRefed<gfx::DrawTarget> BorrowDrawTarget(
const gfx::IntRect& aPersistedRect) override;
@ -160,27 +166,14 @@ class PersistentBufferProviderAccelerated : public PersistentBufferProvider {
already_AddRefed<gfx::SourceSurface> BorrowSnapshot(
gfx::DrawTarget* aTarget) override;
void ReturnSnapshot(already_AddRefed<gfx::SourceSurface> aSnapshot) override;
bool PreservesDrawingState() const override { return true; }
void OnShutdown() override { Destroy(); }
Maybe<SurfaceDescriptor> GetFrontBuffer() override;
bool RequiresRefresh() const override;
void OnMemoryPressure() override;
protected:
explicit PersistentBufferProviderAccelerated(
const RefPtr<TextureClient>& aTexture);
~PersistentBufferProviderAccelerated() override;
void Destroy();
RefPtr<TextureClient> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
RefPtr<gfx::SourceSurface> mSnapshot;
gfx::DrawTargetWebgl* GetDrawTargetWebgl() const;
};
/**

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

@ -40,7 +40,6 @@ const EventType REMOVE_SURFACE_ALIAS = EventType(EventType::LAST + 9);
const EventType DEVICE_CHANGE_ACKNOWLEDGED = EventType(EventType::LAST + 10);
const EventType NEXT_TEXTURE_ID = EventType(EventType::LAST + 11);
const EventType TEXTURE_DESTRUCTION = EventType(EventType::LAST + 12);
const EventType PREPARE_SHMEM = EventType(EventType::LAST + 13);
class RecordedCanvasBeginTransaction final
: public RecordedEventDerived<RecordedCanvasBeginTransaction> {
@ -134,12 +133,10 @@ RecordedCanvasFlush::RecordedCanvasFlush(S& aStream)
class RecordedTextureLock final
: public RecordedEventDerived<RecordedTextureLock> {
public:
RecordedTextureLock(int64_t aTextureId, const OpenMode aMode,
RemoteTextureId aId)
RecordedTextureLock(int64_t aTextureId, const OpenMode aMode)
: RecordedEventDerived(TEXTURE_LOCK),
mTextureId(aTextureId),
mMode(aMode),
mLastRemoteTextureId(aId) {}
mMode(aMode) {}
template <class S>
MOZ_IMPLICIT RecordedTextureLock(S& aStream);
@ -154,14 +151,16 @@ class RecordedTextureLock final
private:
int64_t mTextureId;
OpenMode mMode;
RemoteTextureId mLastRemoteTextureId;
};
inline bool RecordedTextureLock::PlayCanvasEvent(
CanvasTranslator* aTranslator) const {
if (!aTranslator->LockTexture(mTextureId, mMode, mLastRemoteTextureId)) {
TextureData* textureData = aTranslator->LookupTextureData(mTextureId);
if (!textureData) {
return false;
}
textureData->Lock(mMode);
return true;
}
@ -169,7 +168,6 @@ template <class S>
void RecordedTextureLock::Record(S& aStream) const {
WriteElement(aStream, mTextureId);
WriteElement(aStream, mMode);
WriteElement(aStream, mLastRemoteTextureId.mId);
}
template <class S>
@ -178,16 +176,13 @@ RecordedTextureLock::RecordedTextureLock(S& aStream)
ReadElement(aStream, mTextureId);
ReadElementConstrained(aStream, mMode, OpenMode::OPEN_NONE,
OpenMode::OPEN_READ_WRITE_ASYNC);
ReadElement(aStream, mLastRemoteTextureId.mId);
}
class RecordedTextureUnlock final
: public RecordedEventDerived<RecordedTextureUnlock> {
public:
explicit RecordedTextureUnlock(int64_t aTextureId, RemoteTextureId aId)
: RecordedEventDerived(TEXTURE_UNLOCK),
mTextureId(aTextureId),
mLastRemoteTextureId(aId) {}
explicit RecordedTextureUnlock(int64_t aTextureId)
: RecordedEventDerived(TEXTURE_UNLOCK), mTextureId(aTextureId) {}
template <class S>
MOZ_IMPLICIT RecordedTextureUnlock(S& aStream);
@ -201,28 +196,28 @@ class RecordedTextureUnlock final
private:
int64_t mTextureId;
RemoteTextureId mLastRemoteTextureId;
};
inline bool RecordedTextureUnlock::PlayCanvasEvent(
CanvasTranslator* aTranslator) const {
if (!aTranslator->UnlockTexture(mTextureId, mLastRemoteTextureId)) {
TextureData* textureData = aTranslator->LookupTextureData(mTextureId);
if (!textureData) {
return false;
}
textureData->Unlock();
return true;
}
template <class S>
void RecordedTextureUnlock::Record(S& aStream) const {
WriteElement(aStream, mTextureId);
WriteElement(aStream, mLastRemoteTextureId.mId);
}
template <class S>
RecordedTextureUnlock::RecordedTextureUnlock(S& aStream)
: RecordedEventDerived(TEXTURE_UNLOCK) {
ReadElement(aStream, mTextureId);
ReadElement(aStream, mLastRemoteTextureId.mId);
}
class RecordedCacheDataSurface final
@ -330,11 +325,8 @@ RecordedPrepareDataForSurface::RecordedPrepareDataForSurface(S& aStream)
class RecordedGetDataForSurface final
: public RecordedEventDerived<RecordedGetDataForSurface> {
public:
RecordedGetDataForSurface(const gfx::SourceSurface* aSurface,
const gfx::IntRect& aRect)
: RecordedEventDerived(GET_DATA_FOR_SURFACE),
mSurface(aSurface),
mRect(aRect) {}
explicit RecordedGetDataForSurface(const gfx::SourceSurface* aSurface)
: RecordedEventDerived(GET_DATA_FOR_SURFACE), mSurface(aSurface) {}
template <class S>
MOZ_IMPLICIT RecordedGetDataForSurface(S& aStream);
@ -348,7 +340,6 @@ class RecordedGetDataForSurface final
private:
ReferencePtr mSurface;
gfx::IntRect mRect;
};
inline bool RecordedGetDataForSurface::PlayCanvasEvent(
@ -358,25 +349,21 @@ inline bool RecordedGetDataForSurface::PlayCanvasEvent(
return false;
}
if (!surface->GetRect().Contains(mRect)) {
return false;
}
UniquePtr<gfx::DataSourceSurface::ScopedMap> map =
aTranslator->GetPreparedMap(mSurface);
if (!map) {
return false;
}
int32_t bpp = BytesPerPixel(surface->GetFormat());
int32_t dataFormatWidth = mRect.width * bpp;
int32_t dataFormatWidth =
surface->GetSize().width * BytesPerPixel(surface->GetFormat());
int32_t srcStride = map->GetStride();
if (dataFormatWidth > srcStride) {
return false;
}
uint8_t* src = map->GetData() + mRect.y * srcStride + mRect.x * bpp;
uint8_t* endSrc = src + mRect.height * srcStride;
char* src = reinterpret_cast<char*>(map->GetData());
char* endSrc = src + (map->GetSurface()->GetSize().height * srcStride);
while (src < endSrc) {
aTranslator->ReturnWrite(src, dataFormatWidth);
src += srcStride;
@ -388,14 +375,12 @@ inline bool RecordedGetDataForSurface::PlayCanvasEvent(
template <class S>
void RecordedGetDataForSurface::Record(S& aStream) const {
WriteElement(aStream, mSurface);
WriteElement(aStream, mRect);
}
template <class S>
RecordedGetDataForSurface::RecordedGetDataForSurface(S& aStream)
: RecordedEventDerived(GET_DATA_FOR_SURFACE) {
ReadElement(aStream, mSurface);
ReadElement(aStream, mRect);
}
class RecordedAddSurfaceAlias final
@ -520,11 +505,8 @@ RecordedDeviceChangeAcknowledged::RecordedDeviceChangeAcknowledged(S& aStream)
class RecordedNextTextureId final
: public RecordedEventDerived<RecordedNextTextureId> {
public:
RecordedNextTextureId(int64_t aNextTextureId,
RemoteTextureOwnerId aRemoteTextureOwnerId)
: RecordedEventDerived(NEXT_TEXTURE_ID),
mNextTextureId(aNextTextureId),
mRemoteTextureOwnerId(aRemoteTextureOwnerId) {}
explicit RecordedNextTextureId(int64_t aNextTextureId)
: RecordedEventDerived(NEXT_TEXTURE_ID), mNextTextureId(aNextTextureId) {}
template <class S>
MOZ_IMPLICIT RecordedNextTextureId(S& aStream);
@ -537,28 +519,24 @@ class RecordedNextTextureId final
std::string GetName() const final { return "RecordedNextTextureId"; }
private:
int64_t mNextTextureId = 0;
RemoteTextureOwnerId mRemoteTextureOwnerId;
RemoteTextureId mRemoteTextureId;
int64_t mNextTextureId;
};
inline bool RecordedNextTextureId::PlayCanvasEvent(
CanvasTranslator* aTranslator) const {
aTranslator->SetNextTextureId(mNextTextureId, mRemoteTextureOwnerId);
aTranslator->SetNextTextureId(mNextTextureId);
return true;
}
template <class S>
void RecordedNextTextureId::Record(S& aStream) const {
WriteElement(aStream, mNextTextureId);
WriteElement(aStream, mRemoteTextureOwnerId.mId);
}
template <class S>
RecordedNextTextureId::RecordedNextTextureId(S& aStream)
: RecordedEventDerived(NEXT_TEXTURE_ID) {
ReadElement(aStream, mNextTextureId);
ReadElement(aStream, mRemoteTextureOwnerId.mId);
}
class RecordedTextureDestruction final
@ -578,7 +556,7 @@ class RecordedTextureDestruction final
std::string GetName() const final { return "RecordedTextureDestruction"; }
private:
int64_t mTextureId = 0;
int64_t mTextureId;
};
inline bool RecordedTextureDestruction::PlayCanvasEvent(
@ -598,43 +576,6 @@ RecordedTextureDestruction::RecordedTextureDestruction(S& aStream)
ReadElement(aStream, mTextureId);
}
class RecordedPrepareShmem final
: public RecordedEventDerived<RecordedPrepareShmem> {
public:
explicit RecordedPrepareShmem(int64_t aTextureId)
: RecordedEventDerived(PREPARE_SHMEM), mTextureId(aTextureId) {}
template <class S>
MOZ_IMPLICIT RecordedPrepareShmem(S& aStream);
bool PlayCanvasEvent(CanvasTranslator* aTranslator) const;
template <class S>
void Record(S& aStream) const;
std::string GetName() const final { return "RecordedPrepareShmem"; }
private:
int64_t mTextureId = 0;
};
inline bool RecordedPrepareShmem::PlayCanvasEvent(
CanvasTranslator* aTranslator) const {
aTranslator->PrepareShmem(mTextureId);
return true;
}
template <class S>
void RecordedPrepareShmem::Record(S& aStream) const {
WriteElement(aStream, mTextureId);
}
template <class S>
RecordedPrepareShmem::RecordedPrepareShmem(S& aStream)
: RecordedEventDerived(PREPARE_SHMEM) {
ReadElement(aStream, mTextureId);
}
#define FOR_EACH_CANVAS_EVENT(f) \
f(CANVAS_BEGIN_TRANSACTION, RecordedCanvasBeginTransaction); \
f(CANVAS_END_TRANSACTION, RecordedCanvasEndTransaction); \
@ -648,8 +589,7 @@ RecordedPrepareShmem::RecordedPrepareShmem(S& aStream)
f(REMOVE_SURFACE_ALIAS, RecordedRemoveSurfaceAlias); \
f(DEVICE_CHANGE_ACKNOWLEDGED, RecordedDeviceChangeAcknowledged); \
f(NEXT_TEXTURE_ID, RecordedNextTextureId); \
f(TEXTURE_DESTRUCTION, RecordedTextureDestruction); \
f(PREPARE_SHMEM, RecordedPrepareShmem);
f(TEXTURE_DESTRUCTION, RecordedTextureDestruction);
} // namespace layers
} // namespace mozilla

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

@ -217,7 +217,7 @@ void RemoteTextureMap::Shutdown() {
}
}
RemoteTextureMap::RemoteTextureMap() : mMonitor("RemoteTextureMap::mMonitor") {}
RemoteTextureMap::RemoteTextureMap() : mMonitor("D3D11TextureMap::mMonitor") {}
RemoteTextureMap::~RemoteTextureMap() = default;
@ -314,7 +314,17 @@ void RemoteTextureMap::PushTexture(
// used by WebRender anymore.
if (front->mTextureHost &&
front->mTextureHost->NumCompositableRefs() == 0) {
owner->mReleasingTextureDataHolders.push_back(std::move(front));
// Recycle SharedTexture
if (front->mResourceWrapper) {
owner->mRecycledSharedTextures.push(
std::move(front->mResourceWrapper));
}
// Recycle BufferTextureData
if (!(front->mTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE) &&
(front->mTextureData &&
front->mTextureData->AsBufferTextureData())) {
owner->mRecycledTextures.push(std::move(front->mTextureData));
}
owner->mUsingTextureDataHolders.pop_front();
} else if (front->mTextureHost &&
front->mTextureHost->NumCompositableRefs() >= 0) {
@ -325,19 +335,6 @@ void RemoteTextureMap::PushTexture(
owner->mUsingTextureDataHolders.pop_front();
}
}
while (!owner->mReleasingTextureDataHolders.empty()) {
auto& front = owner->mReleasingTextureDataHolders.front();
// Recycle SharedTexture
if (front->mResourceWrapper) {
owner->mRecycledSharedTextures.push(std::move(front->mResourceWrapper));
}
// Recycle BufferTextureData
if (!(front->mTextureHost->GetFlags() & TextureFlags::DUMMY_TEXTURE) &&
(front->mTextureData && front->mTextureData->AsBufferTextureData())) {
owner->mRecycledTextures.push(std::move(front->mTextureData));
}
owner->mReleasingTextureDataHolders.pop_front();
}
}
const auto info = RemoteTextureInfo(aTextureId, aOwnerId, aForPid);
@ -448,7 +445,8 @@ void RemoteTextureMap::KeepTextureDataAliveForTextureHostIfNecessary(
// SharedResourceWrapper/TextureData alive while the TextureHost is alive.
if (holder->mTextureHost &&
holder->mTextureHost->NumCompositableRefs() >= 0) {
RefPtr<nsISerialEventTarget> eventTarget = GetCurrentSerialEventTarget();
RefPtr<nsISerialEventTarget> eventTarget =
MessageLoop::current()->SerialEventTarget();
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
"RemoteTextureMap::UnregisterTextureOwner::Runnable",
[data = std::move(holder->mTextureData),
@ -513,9 +511,6 @@ void RemoteTextureMap::UnregisterTextureOwner(
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mUsingTextureDataHolders);
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mReleasingTextureDataHolders);
releasingOwner = std::move(it->second);
mTextureOwners.erase(it);
@ -582,9 +577,6 @@ void RemoteTextureMap::UnregisterTextureOwners(
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mUsingTextureDataHolders);
KeepTextureDataAliveForTextureHostIfNecessary(
lock, it->second->mReleasingTextureDataHolders);
releasingOwners.push_back(std::move(it->second));
mTextureOwners.erase(it);
}
@ -665,19 +657,6 @@ void RemoteTextureMap::UpdateTexture(const MonitorAutoLock& aProofOfLock,
UniquePtr<TextureDataHolder> holder = std::move(front);
aOwner->mWaitingTextureDataHolders.pop_front();
// If there are textures not being used by the compositor that will be
// obsoleted by this new texture, then queue them for removal later on
// the creating thread.
while (!aOwner->mUsingTextureDataHolders.empty()) {
auto& back = aOwner->mUsingTextureDataHolders.back();
if (back->mTextureHost &&
back->mTextureHost->NumCompositableRefs() == 0) {
aOwner->mReleasingTextureDataHolders.push_back(std::move(back));
aOwner->mUsingTextureDataHolders.pop_back();
continue;
}
break;
}
aOwner->mUsingTextureDataHolders.push_back(std::move(holder));
}
}
@ -717,8 +696,7 @@ RemoteTextureMap::GetAllRenderingReadyCallbacks(
bool RemoteTextureMap::GetRemoteTextureForDisplayList(
RemoteTextureHostWrapper* aTextureHostWrapper,
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback,
bool aWaitForRemoteTextureOwner) {
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback) {
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
MOZ_ASSERT(aTextureHostWrapper);
@ -736,23 +714,8 @@ bool RemoteTextureMap::GetRemoteTextureForDisplayList(
MonitorAutoLock lock(mMonitor);
auto* owner = GetTextureOwner(lock, ownerId, forPid);
// If there is no texture owner yet, then we might need to wait for one to
// be created, if allowed. If so, we must also wait for an initial texture
// host to be created so we can use it.
if (!owner || (aWaitForRemoteTextureOwner && !owner->mLatestTextureHost &&
owner->mWaitingTextureDataHolders.empty())) {
if (!aWaitForRemoteTextureOwner) {
return false;
}
const TimeDuration timeout = TimeDuration::FromMilliseconds(10000);
while (!owner || (!owner->mLatestTextureHost &&
owner->mWaitingTextureDataHolders.empty())) {
CVStatus status = mMonitor.Wait(timeout);
if (status == CVStatus::Timeout) {
return false;
}
owner = GetTextureOwner(lock, ownerId, forPid);
}
if (!owner) {
return false;
}
UpdateTexture(lock, owner, textureId);

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

@ -213,8 +213,7 @@ class RemoteTextureMap {
// return true when aReadyCallback will be called.
bool GetRemoteTextureForDisplayList(
RemoteTextureHostWrapper* aTextureHostWrapper,
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback,
bool aWaitForRemoteTextureOwner = false);
std::function<void(const RemoteTextureInfo&)>&& aReadyCallback);
// Get ExternalImageId of remote texture for WebRender rendering.
wr::MaybeExternalImageId GetExternalImageIdOfRemoteTexture(
@ -298,7 +297,6 @@ class RemoteTextureMap {
std::deque<UniquePtr<TextureDataHolder>> mWaitingTextureDataHolders;
// Holds TextureDataHolders that are used for building wr display list.
std::deque<UniquePtr<TextureDataHolder>> mUsingTextureDataHolders;
std::deque<UniquePtr<TextureDataHolder>> mReleasingTextureDataHolders;
// Holds async RemoteTexture ready callbacks.
std::deque<UniquePtr<RenderingReadyCallbackHolder>>
mRenderingReadyCallbackHolders;

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

@ -318,36 +318,6 @@ static bool ShouldRemoteTextureType(TextureType aTextureType,
}
}
/* static */
TextureData* TextureData::Create(TextureType aTextureType,
gfx::SurfaceFormat aFormat,
const gfx::IntSize& aSize,
TextureAllocationFlags aAllocFlags,
gfx::BackendType aBackendType) {
switch (aTextureType) {
#ifdef XP_WIN
case TextureType::D3D11:
return D3D11TextureData::Create(aSize, aFormat, aAllocFlags);
#endif
#ifdef MOZ_WIDGET_GTK
case TextureType::DMABUF:
return DMABUFTextureData::Create(aSize, aFormat, aBackendType);
#endif
#ifdef XP_MACOSX
case TextureType::MacIOSurface:
return MacIOSurfaceTextureData::Create(aSize, aFormat, aBackendType);
#endif
#ifdef MOZ_WIDGET_ANDROID
case TextureType::AndroidNativeWindow:
return AndroidNativeWindowTextureData::Create(aSize, aFormat);
#endif
default:
return nullptr;
}
}
/* static */
TextureData* TextureData::Create(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
@ -358,33 +328,45 @@ TextureData* TextureData::Create(TextureForwarder* aAllocator,
TextureType textureType =
GetTextureType(aFormat, aSize, aKnowsCompositor, aSelector, aAllocFlags);
if ((aAllocFlags & ALLOC_FORCE_REMOTE) ||
ShouldRemoteTextureType(textureType, aSelector)) {
if (ShouldRemoteTextureType(textureType, aSelector)) {
RefPtr<CanvasChild> canvasChild = aAllocator->GetCanvasChild();
if (canvasChild) {
return new RecordedTextureData(canvasChild.forget(), aSize, aFormat,
textureType);
}
if (aAllocFlags & ALLOC_FORCE_REMOTE) {
// If we must be remote, but there is no canvas child, then falling back
// is not possible.
return nullptr;
}
// We don't have a CanvasChild, but are supposed to be remote.
// Fall back to software.
textureType = TextureType::Unknown;
}
gfx::BackendType moz2DBackend = gfx::BackendType::NONE;
#if defined(XP_MACOSX) || defined(MOZ_WIDGET_GTK)
moz2DBackend = BackendTypeForBackendSelector(
gfx::BackendType moz2DBackend = BackendTypeForBackendSelector(
aKnowsCompositor->GetCompositorBackendType(), aSelector);
#endif
return TextureData::Create(textureType, aFormat, aSize, aAllocFlags,
moz2DBackend);
switch (textureType) {
#ifdef XP_WIN
case TextureType::D3D11:
return D3D11TextureData::Create(aSize, aFormat, aAllocFlags);
#endif
#ifdef MOZ_WIDGET_GTK
case TextureType::DMABUF:
return DMABUFTextureData::Create(aSize, aFormat, moz2DBackend);
#endif
#ifdef XP_MACOSX
case TextureType::MacIOSurface:
return MacIOSurfaceTextureData::Create(aSize, aFormat, moz2DBackend);
#endif
#ifdef MOZ_WIDGET_ANDROID
case TextureType::AndroidNativeWindow:
return AndroidNativeWindowTextureData::Create(aSize, aFormat);
#endif
default:
return nullptr;
}
}
/* static */
@ -1177,10 +1159,6 @@ already_AddRefed<TextureClient> TextureClient::CreateForDrawing(
if (data) {
return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
}
if (aAllocFlags & ALLOC_FORCE_REMOTE) {
// If we must be remote, but allocation failed, then don't fall back.
return nullptr;
}
// Can't do any better than a buffer texture client.
return TextureClient::CreateForRawBufferAccess(aAllocator, aFormat, aSize,

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

@ -69,7 +69,6 @@ class SharedSurfaceTextureData;
class TextureClientPool;
#endif
class TextureForwarder;
struct RemoteTextureOwnerId;
/**
* TextureClient is the abstraction that allows us to share data between the
@ -99,9 +98,6 @@ enum TextureAllocationFlags {
// Do not use an accelerated texture type.
ALLOC_DO_NOT_ACCELERATE = 1 << 8,
// Force allocation of remote/recorded texture, or fail if not possible.
ALLOC_FORCE_REMOTE = 1 << 9,
};
enum class BackendSelector { Content, Canvas };
@ -226,10 +222,6 @@ class TextureData {
canConcurrentlyReadLock(true) {}
};
static TextureData* Create(
TextureType aTextureType, gfx::SurfaceFormat aFormat,
const gfx::IntSize& aSize, TextureAllocationFlags aAllocFlags,
gfx::BackendType aBackendType = gfx::BackendType::NONE);
static TextureData* Create(TextureForwarder* aAllocator,
gfx::SurfaceFormat aFormat, gfx::IntSize aSize,
KnowsCompositor* aKnowsCompositor,
@ -319,10 +311,6 @@ class TextureData {
return mozilla::ipc::FileDescriptor();
}
virtual void SetRemoteTextureOwnerId(RemoteTextureOwnerId) {}
virtual bool RequiresRefresh() const { return false; }
protected:
MOZ_COUNTED_DEFAULT_CTOR(TextureData)
};

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

@ -30,7 +30,6 @@ RecordedTextureData::~RecordedTextureData() {
// We need the translator to drop its reference for the DrawTarget first,
// because the TextureData might need to destroy its DrawTarget within a lock.
mDT = nullptr;
mCanvasChild->CleanupTexture(mTextureId);
mCanvasChild->RecordEvent(RecordedTextureDestruction(mTextureId));
}
@ -41,25 +40,15 @@ void RecordedTextureData::FillInfo(TextureData::Info& aInfo) const {
aInfo.hasSynchronization = true;
}
void RecordedTextureData::SetRemoteTextureOwnerId(
RemoteTextureOwnerId aRemoteTextureOwnerId) {
mRemoteTextureOwnerId = aRemoteTextureOwnerId;
}
bool RecordedTextureData::Lock(OpenMode aMode) {
if (!mCanvasChild->EnsureBeginTransaction()) {
return false;
}
if (mRemoteTextureOwnerId.IsValid()) {
mLastRemoteTextureId = RemoteTextureId::GetNext();
}
if (!mDT) {
mTextureId = sNextRecordedTextureId++;
mCanvasChild->RecordEvent(
RecordedNextTextureId(mTextureId, mRemoteTextureOwnerId));
mDT = mCanvasChild->CreateDrawTarget(mTextureId, mSize, mFormat);
mCanvasChild->RecordEvent(RecordedNextTextureId(mTextureId));
mDT = mCanvasChild->CreateDrawTarget(mSize, mFormat);
if (!mDT) {
return false;
}
@ -70,8 +59,7 @@ bool RecordedTextureData::Lock(OpenMode aMode) {
return true;
}
mCanvasChild->RecordEvent(
RecordedTextureLock(mTextureId, aMode, mLastRemoteTextureId));
mCanvasChild->RecordEvent(RecordedTextureLock(mTextureId, aMode));
if (aMode & OpenMode::OPEN_WRITE) {
mCanvasChild->OnTextureWriteLock();
}
@ -87,18 +75,12 @@ void RecordedTextureData::Unlock() {
mCanvasChild->RecordEvent(RecordedCacheDataSurface(mSnapshot.get()));
}
mCanvasChild->RecordEvent(
RecordedTextureUnlock(mTextureId, mLastRemoteTextureId));
mCanvasChild->RecordEvent(RecordedTextureUnlock(mTextureId));
mLockedMode = OpenMode::OPEN_NONE;
}
already_AddRefed<gfx::DrawTarget> RecordedTextureData::BorrowDrawTarget() {
mSnapshot = nullptr;
if (RefPtr<gfx::SourceSurface> wrapper = do_AddRef(mSnapshotWrapper)) {
mCanvasChild->DetachSurface(wrapper);
mSnapshotWrapper = nullptr;
}
return do_AddRef(mDT);
}
@ -113,31 +95,23 @@ void RecordedTextureData::EndDraw() {
}
already_AddRefed<gfx::SourceSurface> RecordedTextureData::BorrowSnapshot() {
if (RefPtr<gfx::SourceSurface> wrapper = do_AddRef(mSnapshotWrapper)) {
return wrapper.forget();
}
// There are some failure scenarios where we have no DrawTarget and
// BorrowSnapshot is called in an attempt to copy to a new texture.
if (!mDT) {
return nullptr;
}
RefPtr<gfx::SourceSurface> wrapper = mCanvasChild->WrapSurface(
mSnapshot ? mSnapshot : mDT->Snapshot(), mTextureId);
mSnapshotWrapper = wrapper;
return wrapper.forget();
if (mSnapshot) {
return mCanvasChild->WrapSurface(mSnapshot);
}
return mCanvasChild->WrapSurface(mDT->Snapshot());
}
void RecordedTextureData::Deallocate(LayersIPCChannel* aAllocator) {}
bool RecordedTextureData::Serialize(SurfaceDescriptor& aDescriptor) {
if (mRemoteTextureOwnerId.IsValid()) {
aDescriptor = SurfaceDescriptorRemoteTexture(mLastRemoteTextureId,
mRemoteTextureOwnerId);
} else {
aDescriptor = SurfaceDescriptorRecorded(mTextureId);
}
aDescriptor = SurfaceDescriptorRecorded(mTextureId);
return true;
}
@ -151,9 +125,5 @@ TextureFlags RecordedTextureData::GetTextureFlags() const {
return TextureFlags::WAIT_HOST_USAGE_END;
}
bool RecordedTextureData::RequiresRefresh() const {
return mCanvasChild->RequiresRefresh(mTextureId);
}
} // namespace layers
} // namespace mozilla

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

@ -40,11 +40,6 @@ class RecordedTextureData final : public TextureData {
TextureFlags GetTextureFlags() const final;
void SetRemoteTextureOwnerId(
RemoteTextureOwnerId aRemoteTextureOwnerId) final;
bool RequiresRefresh() const final;
private:
DISALLOW_COPY_AND_ASSIGN(RecordedTextureData);
@ -56,10 +51,7 @@ class RecordedTextureData final : public TextureData {
gfx::SurfaceFormat mFormat;
RefPtr<gfx::DrawTarget> mDT;
RefPtr<gfx::SourceSurface> mSnapshot;
ThreadSafeWeakPtr<gfx::SourceSurface> mSnapshotWrapper;
OpenMode mLockedMode;
layers::RemoteTextureId mLastRemoteTextureId;
layers::RemoteTextureOwnerId mRemoteTextureOwnerId;
};
} // namespace layers

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

@ -15,7 +15,6 @@
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/layers/CanvasDrawEventRecorder.h"
#include "mozilla/layers/ImageDataSerializer.h"
#include "nsIObserverService.h"
#include "RecordedCanvasEventImpl.h"
@ -55,11 +54,10 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceCanvasRecording, final)
SourceSurfaceCanvasRecording(
int64_t aTextureId, const RefPtr<gfx::SourceSurface>& aRecordedSuface,
const RefPtr<gfx::SourceSurface>& aRecordedSuface,
CanvasChild* aCanvasChild,
const RefPtr<CanvasDrawEventRecorder>& aRecorder)
: mTextureId(aTextureId),
mRecordedSurface(aRecordedSuface),
: mRecordedSurface(aRecordedSuface),
mCanvasChild(aCanvasChild),
mRecorder(aRecorder) {
// It's important that AddStoredObject is called first because that will
@ -100,23 +98,11 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
return do_AddRef(mDataSourceSurface);
}
bool ReadInto(gfx::DataSourceSurface* aSurface,
const gfx::IntRect& aRect) final {
if (!NS_IsMainThread()) {
return false;
}
return mCanvasChild->ReadInto(mTextureId, mRecordedSurface, aSurface, aRect,
mDetached);
}
void DrawTargetWillChange() { mDetached = true; }
private:
void EnsureDataSurfaceOnMainThread() {
// The data can only be retrieved on the main thread.
if (!mDataSourceSurface && NS_IsMainThread()) {
mDataSourceSurface =
mCanvasChild->GetDataSurface(mTextureId, mRecordedSurface, mDetached);
mDataSourceSurface = mCanvasChild->GetDataSurface(mRecordedSurface);
}
}
@ -134,12 +120,10 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
aRecorder = nullptr;
}
int64_t mTextureId;
RefPtr<gfx::SourceSurface> mRecordedSurface;
RefPtr<CanvasChild> mCanvasChild;
RefPtr<CanvasDrawEventRecorder> mRecorder;
RefPtr<gfx::DataSourceSurface> mDataSourceSurface;
bool mDetached = false;
};
CanvasChild::CanvasChild() = default;
@ -171,13 +155,6 @@ ipc::IPCResult CanvasChild::RecvDeactivate() {
return IPC_OK();
}
ipc::IPCResult CanvasChild::RecvBlockCanvas() {
if (auto* cm = gfx::CanvasManagerChild::Get()) {
cm->BlockCanvas();
}
return IPC_OK();
}
void CanvasChild::EnsureRecorder(TextureType aTextureType) {
if (!mRecorder) {
MOZ_ASSERT(mTextureType == TextureType::Unknown);
@ -193,9 +170,7 @@ void CanvasChild::EnsureRecorder(TextureType aTextureType) {
}
if (CanSend()) {
gfx::BackendType backendType =
gfxPlatform::GetPlatform()->GetPreferredCanvasBackend();
Unused << SendInitTranslator(mTextureType, backendType, std::move(handle),
Unused << SendInitTranslator(mTextureType, std::move(handle),
std::move(readerSem), std::move(writerSem),
/* aUseIPDLThread */ false);
}
@ -318,7 +293,7 @@ bool CanvasChild::ShouldBeCleanedUp() const {
}
already_AddRefed<gfx::DrawTarget> CanvasChild::CreateDrawTarget(
int64_t aTextureId, gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
gfx::IntSize aSize, gfx::SurfaceFormat aFormat) {
// We drop mRecorder in ActorDestroy to break the reference cycle.
if (!mRecorder) {
return nullptr;
@ -328,9 +303,6 @@ already_AddRefed<gfx::DrawTarget> CanvasChild::CreateDrawTarget(
gfx::BackendType::SKIA, gfx::IntSize(1, 1), aFormat);
RefPtr<gfx::DrawTarget> dt = MakeAndAddRef<gfx::DrawTargetRecording>(
mRecorder, dummyDt, gfx::IntRect(gfx::IntPoint(0, 0), aSize));
mTextureInfo.insert({aTextureId, {}});
return dt.forget();
}
@ -344,37 +316,13 @@ void CanvasChild::RecordEvent(const gfx::RecordedEvent& aEvent) {
}
already_AddRefed<gfx::DataSourceSurface> CanvasChild::GetDataSurface(
int64_t aTextureId, const gfx::SourceSurface* aSurface, bool aDetached) {
gfx::IntSize ssSize = aSurface->GetSize();
gfx::SurfaceFormat ssFormat = aSurface->GetFormat();
int32_t dataStride =
gfx::GetAlignedStride<4>(ssSize.width, BytesPerPixel(ssFormat));
RefPtr<gfx::DataSourceSurface> dataSurface =
gfx::Factory::CreateDataSourceSurfaceWithStride(ssSize, ssFormat,
dataStride);
if (!dataSurface) {
gfxWarning() << "Failed to create DataSourceSurface.";
return nullptr;
}
if (!ReadInto(aTextureId, aSurface, dataSurface, aSurface->GetRect(),
aDetached)) {
return nullptr;
}
return dataSurface.forget();
}
bool CanvasChild::ReadInto(int64_t aTextureId,
const gfx::SourceSurface* aSurface,
gfx::DataSourceSurface* aDataSurface,
const gfx::IntRect& aRect, bool aDetached) {
const gfx::SourceSurface* aSurface) {
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aSurface);
// We drop mRecorder in ActorDestroy to break the reference cycle.
if (!mRecorder) {
return false;
return nullptr;
}
// mTransactionsSinceGetDataSurface is used to determine if we want to prepare
@ -386,117 +334,45 @@ bool CanvasChild::ReadInto(int64_t aTextureId,
}
if (!EnsureBeginTransaction()) {
return false;
}
// Shmem is only valid if the surface is the latest snapshot (not detached).
if (!aDetached) {
// If there is a shmem associated with this snapshot id, then we want to try
// read directly from the shmem contents into the destination buffer without
// going through the event ringbuffer.
auto it = mTextureInfo.find(aTextureId);
if (it != mTextureInfo.end() && it->second.mSnapshotShmem.IsReadable()) {
ipc::Shmem& shmem = it->second.mSnapshotShmem;
mRecorder->RecordEvent(RecordedPrepareShmem(aTextureId));
uint32_t checkpoint = mRecorder->CreateCheckpoint();
if (!mRecorder->WaitForCheckpoint(checkpoint)) {
gfxWarning() << "Timed out preparing Shmem.";
return true;
}
gfx::DataSourceSurface::ScopedMap map(aDataSurface,
gfx::DataSourceSurface::READ_WRITE);
if (!map.IsMapped()) {
gfxWarning() << "Failed mapping DataSourceSurface.";
return false;
}
gfx::IntSize size = aSurface->GetSize();
gfx::SurfaceFormat format = aSurface->GetFormat();
auto bpp = BytesPerPixel(format);
auto stride = ImageDataSerializer::ComputeRGBStride(format, size.width);
const uint8_t* srcPtr =
shmem.get<uint8_t>() + aRect.y * stride + aRect.x * bpp;
uint8_t* dstPtr = map.GetData();
for (int32_t y = 0; y < aRect.height; y++) {
memcpy(dstPtr, srcPtr, bpp * aRect.width);
srcPtr += stride;
dstPtr += map.GetStride();
}
return true;
}
return nullptr;
}
mRecorder->RecordEvent(RecordedPrepareDataForSurface(aSurface));
uint32_t checkpoint = mRecorder->CreateCheckpoint();
gfx::DataSourceSurface::ScopedMap map(aDataSurface,
gfx::IntSize ssSize = aSurface->GetSize();
gfx::SurfaceFormat ssFormat = aSurface->GetFormat();
size_t dataFormatWidth = ssSize.width * BytesPerPixel(ssFormat);
RefPtr<gfx::DataSourceSurface> dataSurface =
gfx::Factory::CreateDataSourceSurfaceWithStride(ssSize, ssFormat,
dataFormatWidth);
if (!dataSurface) {
gfxWarning() << "Failed to create DataSourceSurface.";
return nullptr;
}
gfx::DataSourceSurface::ScopedMap map(dataSurface,
gfx::DataSourceSurface::READ_WRITE);
char* dest = reinterpret_cast<char*>(map.GetData());
if (!mRecorder->WaitForCheckpoint(checkpoint)) {
gfxWarning() << "Timed out preparing data for DataSourceSurface.";
return true;
return dataSurface.forget();
}
if (!map.IsMapped()) {
gfxWarning() << "Failed mapping DataSourceSurface.";
return false;
}
mRecorder->RecordEvent(RecordedGetDataForSurface(aSurface));
mRecorder->ReturnRead(dest, ssSize.height * dataFormatWidth);
mRecorder->RecordEvent(RecordedGetDataForSurface(aSurface, aRect));
mRecorder->ReturnRead(map.GetData(), aDataSurface->GetSize(),
BytesPerPixel(aDataSurface->GetFormat()),
map.GetStride());
return true;
return dataSurface.forget();
}
already_AddRefed<gfx::SourceSurface> CanvasChild::WrapSurface(
const RefPtr<gfx::SourceSurface>& aSurface, int64_t aTextureId) {
const RefPtr<gfx::SourceSurface>& aSurface) {
MOZ_ASSERT(aSurface);
// We drop mRecorder in ActorDestroy to break the reference cycle.
if (!mRecorder) {
return nullptr;
}
return MakeAndAddRef<SourceSurfaceCanvasRecording>(aTextureId, aSurface, this,
mRecorder);
}
void CanvasChild::DetachSurface(const RefPtr<gfx::SourceSurface>& aSurface) {
if (auto* surface =
static_cast<SourceSurfaceCanvasRecording*>(aSurface.get())) {
surface->DrawTargetWillChange();
}
}
ipc::IPCResult CanvasChild::RecvNotifyRequiresRefresh(int64_t aTextureId) {
auto it = mTextureInfo.find(aTextureId);
if (it != mTextureInfo.end()) {
it->second.mRequiresRefresh = true;
}
return IPC_OK();
}
bool CanvasChild::RequiresRefresh(int64_t aTextureId) const {
auto it = mTextureInfo.find(aTextureId);
if (it != mTextureInfo.end()) {
return it->second.mRequiresRefresh;
}
return false;
}
ipc::IPCResult CanvasChild::RecvSnapshotShmem(
int64_t aTextureId, Shmem&& aShmem, SnapshotShmemResolver&& aResolve) {
auto it = mTextureInfo.find(aTextureId);
if (it != mTextureInfo.end()) {
it->second.mSnapshotShmem = std::move(aShmem);
aResolve(true);
} else {
aResolve(false);
}
return IPC_OK();
}
void CanvasChild::CleanupTexture(int64_t aTextureId) {
mTextureInfo.erase(aTextureId);
return MakeAndAddRef<SourceSurfaceCanvasRecording>(aSurface, this, mRecorder);
}
} // namespace layers

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

@ -44,13 +44,6 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
ipc::IPCResult RecvDeactivate();
ipc::IPCResult RecvBlockCanvas();
ipc::IPCResult RecvNotifyRequiresRefresh(int64_t aTextureId);
ipc::IPCResult RecvSnapshotShmem(int64_t aTextureId, Shmem&& aShmem,
SnapshotShmemResolver&& aResolve);
/**
* Ensures that the DrawEventRecorder has been created.
*
@ -105,13 +98,12 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
/**
* Create a DrawTargetRecording for a canvas texture.
* @param aTextureId the id of the new texture
* @param aSize size for the DrawTarget
* @param aFormat SurfaceFormat for the DrawTarget
* @returns newly created DrawTargetRecording
*/
already_AddRefed<gfx::DrawTarget> CreateDrawTarget(
int64_t aTextureId, gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
/**
* Record an event for processing by the CanvasParent's CanvasTranslator.
@ -123,37 +115,21 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
* Wrap the given surface, so that we can provide a DataSourceSurface if
* required.
* @param aSurface the SourceSurface to wrap
* @param aTextureId the texture id of the source TextureData
* @returns a SourceSurface that can provide a DataSourceSurface if required
*/
already_AddRefed<gfx::SourceSurface> WrapSurface(
const RefPtr<gfx::SourceSurface>& aSurface, int64_t aTextureId);
/**
* The DrawTargetRecording is about to change, so detach the old snapshot.
*/
void DetachSurface(const RefPtr<gfx::SourceSurface>& aSurface);
const RefPtr<gfx::SourceSurface>& aSurface);
/**
* Get DataSourceSurface from the translated equivalent version of aSurface in
* the GPU process.
* @param aTextureId the source TextureData to read from
* @param aSurface the SourceSurface in this process for which we need a
* DataSourceSurface
* @param aDetached whether the surface is old
* @returns a DataSourceSurface created from data for aSurface retrieve from
* GPU process
*/
already_AddRefed<gfx::DataSourceSurface> GetDataSurface(
int64_t aTextureId, const gfx::SourceSurface* aSurface, bool aDetached);
bool ReadInto(int64_t aTextureId, const gfx::SourceSurface* aSurface,
gfx::DataSourceSurface* aDataSurface, const gfx::IntRect& aRect,
bool aDetached);
bool RequiresRefresh(int64_t aTextureId) const;
void CleanupTexture(int64_t aTextureId);
const gfx::SourceSurface* aSurface);
protected:
void ActorDestroy(ActorDestroyReason aWhy) final;
@ -173,11 +149,6 @@ class CanvasChild final : public PCanvasChild, public SupportsWeakPtr {
uint32_t mLastWriteLockCheckpoint = 0;
uint32_t mTransactionsSinceGetDataSurface = kCacheDataSurfaceThreshold;
std::vector<RefPtr<gfx::SourceSurface>> mLastTransactionExternalSurfaces;
struct TextureInfo {
ipc::Shmem mSnapshotShmem;
bool mRequiresRefresh = false;
};
std::unordered_map<int64_t, TextureInfo> mTextureInfo;
bool mIsInTransaction = false;
bool mHasOutstandingWriteLock = false;
};

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

@ -7,22 +7,18 @@
#include "CanvasTranslator.h"
#include "gfxGradientCache.h"
#include "gfxPlatform.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/CanvasManagerParent.h"
#include "mozilla/gfx/CanvasRenderThread.h"
#include "mozilla/gfx/DrawTargetWebgl.h"
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/ipc/Endpoint.h"
#include "mozilla/layers/BufferTexture.h"
#include "mozilla/layers/SharedSurfacesParent.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/Telemetry.h"
#include "GLContext.h"
#include "RecordedCanvasEventImpl.h"
#if defined(XP_WIN)
@ -53,7 +49,6 @@ class RingBufferReaderServices final
};
TextureData* CanvasTranslator::CreateTextureData(TextureType aTextureType,
gfx::BackendType aBackendType,
const gfx::IntSize& aSize,
gfx::SurfaceFormat aFormat) {
TextureData* textureData = nullptr;
@ -65,17 +60,8 @@ TextureData* CanvasTranslator::CreateTextureData(TextureType aTextureType,
break;
}
#endif
case TextureType::Unknown:
textureData = BufferTextureData::Create(
aSize, aFormat, gfx::BackendType::SKIA, LayersBackend::LAYERS_WR,
TextureFlags::DEALLOCATE_CLIENT | TextureFlags::REMOTE_TEXTURE,
ALLOC_CLEAR_BUFFER, nullptr);
break;
default:
textureData = TextureData::Create(aTextureType, aFormat, aSize,
ALLOC_CLEAR_BUFFER, aBackendType);
break;
MOZ_CRASH("Unsupported TextureType for CanvasTranslator.");
}
return textureData;
@ -86,7 +72,12 @@ CanvasTranslator::CanvasTranslator() {
Telemetry::ScalarAdd(Telemetry::ScalarID::GFX_CANVAS_REMOTE_ACTIVATED, 1);
}
CanvasTranslator::~CanvasTranslator() = default;
CanvasTranslator::~CanvasTranslator() {
// The textures need to be the last thing holding their DrawTargets, so that
// they can destroy them within a lock.
mDrawTargets.Clear();
mBaseDT = nullptr;
}
void CanvasTranslator::DispatchToTaskQueue(
already_AddRefed<nsIRunnable> aRunnable) {
@ -104,20 +95,8 @@ bool CanvasTranslator::IsInTaskQueue() const {
return gfx::CanvasRenderThread::IsInCanvasRenderThread();
}
bool CanvasTranslator::EnsureSharedContextWebgl() {
if (!mSharedContext || mSharedContext->IsContextLost()) {
mSharedContext = gfx::SharedContextWebgl::Create();
if (!mSharedContext || mSharedContext->IsContextLost()) {
mSharedContext = nullptr;
BlockCanvas();
return false;
}
}
return true;
}
mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
const TextureType& aTextureType, const gfx::BackendType& aBackendType,
const TextureType& aTextureType,
ipc::SharedMemoryBasic::Handle&& aReadHandle,
CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem, const bool& aUseIPDLThread) {
@ -126,7 +105,6 @@ mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
}
mTextureType = aTextureType;
mBackendType = aBackendType;
// We need to initialize the stream first, because it might be used to
// communicate other failures back to the writer.
@ -138,16 +116,13 @@ mozilla::ipc::IPCResult CanvasTranslator::RecvInitTranslator(
return IPC_FAIL(this, "Failed to initialize ring buffer reader.");
}
#if defined(XP_WIN)
if (!CheckForFreshCanvasDevice(__LINE__)) {
gfxCriticalNote << "GFX: CanvasTranslator failed to get device";
mStream = nullptr;
return IPC_OK();
}
if (gfx::gfxVars::UseAcceleratedCanvas2D() && !EnsureSharedContextWebgl()) {
gfxCriticalNote
<< "GFX: CanvasTranslator failed creating WebGL shared context";
}
#endif
if (!aUseIPDLThread) {
mTranslationTaskQueue = gfx::CanvasRenderThread::CreateWorkerTaskQueue();
@ -226,8 +201,6 @@ void CanvasTranslator::FinishShutdown() {
// break the cycle caused by RingBufferReaderServices.
mStream = nullptr;
ClearTextureInfo();
gfx::CanvasManagerParent::RemoveReplayTextures(this);
}
@ -236,8 +209,7 @@ bool CanvasTranslator::CheckDeactivated() {
return true;
}
if (NS_WARN_IF(!gfx::gfxVars::RemoteCanvasEnabled() &&
!gfx::gfxVars::UseAcceleratedCanvas2D())) {
if (NS_WARN_IF(!gfx::gfxVars::RemoteCanvasEnabled())) {
Deactivate();
}
@ -258,26 +230,14 @@ void CanvasTranslator::Deactivate() {
&CanvasTranslator::SendDeactivate));
// Unlock all of our textures.
for (auto const& entry : mTextureInfo) {
if (entry.second.mTextureData) {
entry.second.mTextureData->Unlock();
}
for (auto const& entry : mTextureDatas) {
entry.second->Unlock();
}
// Disable remote canvas for all.
gfx::CanvasManagerParent::DisableRemoteCanvas();
}
void CanvasTranslator::BlockCanvas() {
if (mDeactivated || mBlocked) {
return;
}
mBlocked = true;
gfx::CanvasRenderThread::Dispatch(
NewRunnableMethod("CanvasTranslator::SendBlockCanvas", this,
&CanvasTranslator::SendBlockCanvas));
}
bool CanvasTranslator::TranslateRecording() {
MOZ_ASSERT(IsInTaskQueue());
@ -285,15 +245,6 @@ bool CanvasTranslator::TranslateRecording() {
return false;
}
if (mSharedContext && EnsureSharedContextWebgl()) {
mSharedContext->EnterTlsScope();
}
auto exitTlsScope = MakeScopeExit([&] {
if (mSharedContext) {
mSharedContext->ExitTlsScope();
}
});
uint8_t eventType = mStream->ReadNextEvent();
while (mStream->good() && eventType != kDropBufferEventType) {
bool success = RecordedEvent::DoWithEventFromStream(
@ -410,32 +361,25 @@ bool CanvasTranslator::CreateReferenceTexture() {
mReferenceTextureData->Unlock();
}
mReferenceTextureData.reset(CreateTextureData(mTextureType, mBackendType,
gfx::IntSize(1, 1),
gfx::SurfaceFormat::B8G8R8A8));
mReferenceTextureData.reset(CreateTextureData(
mTextureType, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8A8));
if (!mReferenceTextureData) {
return false;
}
mReferenceTextureData->Lock(OpenMode::OPEN_READ_WRITE);
mBaseDT = mReferenceTextureData->BorrowDrawTarget();
if (!mBaseDT) {
// We might get a null draw target due to a device failure, just return
// false so that we can recover.
return false;
}
mBackendType = mBaseDT->GetBackendType();
return true;
}
bool CanvasTranslator::CheckForFreshCanvasDevice(int aLineNumber) {
// If not on D3D11, we are not dependent on a fresh device for DT creation if
// one already exists.
if (mBaseDT && mTextureType != TextureType::D3D11) {
return false;
}
#if defined(XP_WIN)
// If a new device has already been created, use that one.
RefPtr<ID3D11Device> device = gfx::DeviceManagerDx::Get()->GetCanvasDevice();
@ -475,9 +419,11 @@ bool CanvasTranslator::CheckForFreshCanvasDevice(int aLineNumber) {
Deactivate();
return false;
}
#endif
return CreateReferenceTexture();
#else
return false;
#endif
}
void CanvasTranslator::NotifyDeviceChanged() {
@ -487,117 +433,29 @@ void CanvasTranslator::NotifyDeviceChanged() {
&CanvasTranslator::SendNotifyDeviceChanged));
}
gfx::DrawTargetWebgl* CanvasTranslator::GetDrawTargetWebgl(
int64_t aTextureId) const {
auto result = mTextureInfo.find(aTextureId);
if (result != mTextureInfo.end() && result->second.mDrawTarget &&
result->second.mDrawTarget->GetBackendType() == gfx::BackendType::WEBGL) {
return static_cast<gfx::DrawTargetWebgl*>(result->second.mDrawTarget.get());
}
return nullptr;
}
void CanvasTranslator::NotifyRequiresRefresh(int64_t aTextureId,
bool aDispatch) {
if (aDispatch) {
DispatchToTaskQueue(NewRunnableMethod<int64_t, bool>(
"CanvasTranslator::NotifyRequiresRefresh", this,
&CanvasTranslator::NotifyRequiresRefresh, aTextureId, false));
return;
}
if (mTextureInfo.find(aTextureId) != mTextureInfo.end()) {
Unused << SendNotifyRequiresRefresh(aTextureId);
}
}
void CanvasTranslator::CacheSnapshotShmem(int64_t aTextureId, bool aDispatch) {
if (aDispatch) {
DispatchToTaskQueue(NewRunnableMethod<int64_t, bool>(
"CanvasTranslator::CacheSnapshotShmem", this,
&CanvasTranslator::CacheSnapshotShmem, aTextureId, false));
return;
}
if (gfx::DrawTargetWebgl* webgl = GetDrawTargetWebgl(aTextureId)) {
if (Maybe<Shmem> shmem = webgl->GetShmem()) {
// Lock the DT so that it doesn't get removed while shmem is in transit.
mTextureInfo[aTextureId].mLocked++;
nsCOMPtr<nsIThread> thread =
gfx::CanvasRenderThread::GetCanvasRenderThread();
RefPtr<CanvasTranslator> translator = this;
SendSnapshotShmem(aTextureId, std::move(*shmem))
->Then(
thread, __func__,
[=](bool) { translator->RemoveTexture(aTextureId); },
[=](ipc::ResponseRejectReason) {
translator->RemoveTexture(aTextureId);
});
}
}
}
void CanvasTranslator::PrepareShmem(int64_t aTextureId) {
if (gfx::DrawTargetWebgl* webgl = GetDrawTargetWebgl(aTextureId)) {
webgl->PrepareData();
}
}
already_AddRefed<gfx::DrawTarget> CanvasTranslator::CreateDrawTarget(
gfx::ReferencePtr aRefPtr, const gfx::IntSize& aSize,
gfx::SurfaceFormat aFormat) {
MOZ_DIAGNOSTIC_ASSERT(mNextTextureId >= 0, "No texture ID set");
RefPtr<gfx::DrawTarget> dt;
if (mNextRemoteTextureOwnerId.IsValid()) {
if (EnsureSharedContextWebgl()) {
mSharedContext->EnterTlsScope();
do {
TextureData* textureData = CreateTextureData(mTextureType, aSize, aFormat);
if (textureData) {
MOZ_DIAGNOSTIC_ASSERT(mNextTextureId >= 0, "No texture ID set");
textureData->Lock(OpenMode::OPEN_READ_WRITE);
mTextureDatas[mNextTextureId] = UniquePtr<TextureData>(textureData);
gfx::CanvasManagerParent::AddReplayTexture(this, mNextTextureId,
textureData);
dt = textureData->BorrowDrawTarget();
}
if (RefPtr<gfx::DrawTargetWebgl> webgl = gfx::DrawTargetWebgl::Create(
aSize, aFormat, this, mSharedContext)) {
webgl->BeginFrame(gfx::IntRect());
dt = webgl.forget().downcast<gfx::DrawTarget>();
if (dt) {
TextureInfo& info = mTextureInfo[mNextTextureId];
info.mDrawTarget = dt;
info.mRemoteTextureOwnerId = mNextRemoteTextureOwnerId;
CacheSnapshotShmem(mNextTextureId);
}
}
if (!dt) {
NotifyRequiresRefresh(mNextTextureId);
}
}
if (!dt) {
do {
TextureData* textureData =
CreateTextureData(mTextureType, mBackendType, aSize, aFormat);
if (textureData) {
TextureInfo& info = mTextureInfo[mNextTextureId];
info.mTextureData = UniquePtr<TextureData>(textureData);
info.mRemoteTextureOwnerId = mNextRemoteTextureOwnerId;
if (textureData->Lock(OpenMode::OPEN_READ_WRITE)) {
dt = textureData->BorrowDrawTarget();
}
}
} while (!dt && CheckForFreshCanvasDevice(__LINE__));
}
} while (!dt && CheckForFreshCanvasDevice(__LINE__));
AddDrawTarget(aRefPtr, dt);
mNextTextureId = -1;
mNextRemoteTextureOwnerId = RemoteTextureOwnerId();
return dt.forget();
}
void CanvasTranslator::RemoveTexture(int64_t aTextureId) {
{
// Don't erase the texture if still in use
auto result = mTextureInfo.find(aTextureId);
if (result == mTextureInfo.end() || --result->second.mLocked > 0) {
return;
}
mTextureInfo.erase(result);
}
mTextureDatas.erase(aTextureId);
// It is possible that the texture from the content process has never been
// forwarded from the GPU process, so make sure its descriptor is removed.
@ -605,117 +463,16 @@ void CanvasTranslator::RemoveTexture(int64_t aTextureId) {
}
TextureData* CanvasTranslator::LookupTextureData(int64_t aTextureId) {
auto result = mTextureInfo.find(aTextureId);
if (result == mTextureInfo.end()) {
TextureMap::const_iterator result = mTextureDatas.find(aTextureId);
if (result == mTextureDatas.end()) {
return nullptr;
}
return result->second.mTextureData.get();
}
bool CanvasTranslator::LockTexture(int64_t aTextureId, OpenMode aMode,
RemoteTextureId aId) {
auto result = mTextureInfo.find(aTextureId);
if (result == mTextureInfo.end()) {
return false;
}
if (result->second.mDrawTarget &&
result->second.mDrawTarget->GetBackendType() == gfx::BackendType::WEBGL) {
gfx::DrawTargetWebgl* webgl =
static_cast<gfx::DrawTargetWebgl*>(result->second.mDrawTarget.get());
webgl->BeginFrame(webgl->GetRect());
} else if (TextureData* data = result->second.mTextureData.get()) {
if (!data->Lock(aMode)) {
return false;
}
}
return true;
}
bool CanvasTranslator::UnlockTexture(int64_t aTextureId, RemoteTextureId aId) {
auto result = mTextureInfo.find(aTextureId);
if (result == mTextureInfo.end()) {
return false;
}
RemoteTextureOwnerId ownerId = result->second.mRemoteTextureOwnerId;
if (result->second.mDrawTarget &&
result->second.mDrawTarget->GetBackendType() == gfx::BackendType::WEBGL) {
gfx::DrawTargetWebgl* webgl =
static_cast<gfx::DrawTargetWebgl*>(result->second.mDrawTarget.get());
webgl->EndFrame();
webgl->CopyToSwapChain(aId, ownerId, OtherPid());
if (!result->second.mNotifiedRequiresRefresh && webgl->RequiresRefresh()) {
result->second.mNotifiedRequiresRefresh = true;
NotifyRequiresRefresh(aTextureId);
}
} else if (TextureData* data = result->second.mTextureData.get()) {
if (aId.IsValid()) {
PushRemoteTexture(data, aId, ownerId);
data->Unlock();
} else {
data->Unlock();
gfx::CanvasManagerParent::AddReplayTexture(this, aTextureId, data);
}
}
return true;
}
bool CanvasTranslator::PushRemoteTexture(TextureData* aData,
RemoteTextureId aId,
RemoteTextureOwnerId aOwnerId) {
if (!mRemoteTextureOwner) {
mRemoteTextureOwner = new RemoteTextureOwnerClient(OtherPid());
}
if (!mRemoteTextureOwner->IsRegistered(aOwnerId)) {
mRemoteTextureOwner->RegisterTextureOwner(
aOwnerId,
/* aIsSyncMode */ gfx::gfxVars::WebglOopAsyncPresentForceSync());
}
TextureData::Info info;
aData->FillInfo(info);
UniquePtr<TextureData> dstData;
if (mTextureType == TextureType::Unknown) {
dstData = mRemoteTextureOwner->CreateOrRecycleBufferTextureData(
aOwnerId, info.size, info.format);
} else {
dstData.reset(
CreateTextureData(mTextureType, mBackendType, info.size, info.format));
}
bool success = false;
// Source data is already locked.
if (dstData && dstData->Lock(OpenMode::OPEN_WRITE)) {
if (RefPtr<gfx::DrawTarget> dstDT = dstData->BorrowDrawTarget()) {
if (RefPtr<gfx::DrawTarget> srcDT = aData->BorrowDrawTarget()) {
if (RefPtr<gfx::SourceSurface> snapshot = srcDT->Snapshot()) {
dstDT->CopySurface(snapshot, snapshot->GetRect(),
gfx::IntPoint(0, 0));
success = true;
}
}
}
dstData->Unlock();
}
if (success) {
mRemoteTextureOwner->PushTexture(aId, aOwnerId, std::move(dstData));
} else {
mRemoteTextureOwner->PushDummyTexture(aId, aOwnerId);
}
return success;
}
void CanvasTranslator::ClearTextureInfo() {
mTextureInfo.clear();
mDrawTargets.Clear();
mSharedContext = nullptr;
mBaseDT = nullptr;
if (mRemoteTextureOwner) {
mRemoteTextureOwner->UnregisterAllTextureOwners();
mRemoteTextureOwner = nullptr;
}
return result->second.get();
}
already_AddRefed<gfx::SourceSurface> CanvasTranslator::LookupExternalSurface(
uint64_t aKey) {
return SharedSurfacesParent::Get(wr::ToExternalImageId(aKey), true);
return SharedSurfacesParent::Get(wr::ToExternalImageId(aKey));
}
already_AddRefed<gfx::GradientStops> CanvasTranslator::GetOrCreateGradientStops(

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

@ -14,7 +14,6 @@
#include "mozilla/layers/CanvasDrawEventRecorder.h"
#include "mozilla/layers/LayersSurfaces.h"
#include "mozilla/layers/PCanvasParent.h"
#include "mozilla/layers/RemoteTextureMap.h"
#include "mozilla/ipc/CrossProcessSemaphore.h"
#include "mozilla/Monitor.h"
#include "mozilla/UniquePtr.h"
@ -22,11 +21,6 @@
namespace mozilla {
class TaskQueue;
namespace gfx {
class DrawTargetWebgl;
class SharedContextWebgl;
} // namespace gfx
namespace layers {
class TextureData;
@ -58,7 +52,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* CanvasEventRingBuffer.
*
* @param aTextureType the TextureType the translator will create
* @param aBackendType the BackendType for texture data
* @param aReadHandle handle to the shared memory for the
* CanvasEventRingBuffer
* @param aReaderSem reading blocked semaphore for the CanvasEventRingBuffer
@ -67,7 +60,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* pool for translation requests
*/
ipc::IPCResult RecvInitTranslator(
const TextureType& aTextureType, const gfx::BackendType& aBackendType,
const TextureType& aTextureType,
ipc::SharedMemoryBasic::Handle&& aReadHandle,
CrossProcessSemaphoreHandle&& aReaderSem,
CrossProcessSemaphoreHandle&& aWriterSem, const bool& aUseIPDLThread);
@ -125,7 +118,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* @param aData the data to be written back to the writer
* @param aSize the number of chars to write
*/
void ReturnWrite(const uint8_t* aData, size_t aSize) {
void ReturnWrite(const char* aData, size_t aSize) {
mStream->ReturnWrite(aData, aSize);
}
@ -133,9 +126,8 @@ class CanvasTranslator final : public gfx::InlineTranslator,
* Set the texture ID that will be used as a lookup for the texture created by
* the next CreateDrawTarget.
*/
void SetNextTextureId(int64_t aNextTextureId, RemoteTextureOwnerId aOwnerId) {
void SetNextTextureId(int64_t aNextTextureId) {
mNextTextureId = aNextTextureId;
mNextRemoteTextureOwnerId = aOwnerId;
}
/**
@ -171,12 +163,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
*/
void RemoveTexture(int64_t aTextureId);
bool LockTexture(int64_t aTextureId, OpenMode aMode, RemoteTextureId aId);
bool UnlockTexture(int64_t aTextureId, RemoteTextureId aId);
bool PushRemoteTexture(TextureData* aData, RemoteTextureId aId,
RemoteTextureOwnerId aOwnerId);
/**
* Overriden to remove any DataSourceSurfaces associated with the RefPtr.
*
@ -258,8 +244,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
UniquePtr<gfx::DataSourceSurface::ScopedMap> GetPreparedMap(
gfx::ReferencePtr aSurface);
void PrepareShmem(int64_t aTextureId);
private:
~CanvasTranslator();
@ -273,14 +257,11 @@ class CanvasTranslator final : public gfx::InlineTranslator,
void Deactivate();
void BlockCanvas();
TextureData* CreateTextureData(TextureType aTextureType,
gfx::BackendType aBackendType,
const gfx::IntSize& aSize,
gfx::SurfaceFormat aFormat);
void ClearTextureInfo();
void AddSurfaceDescriptor(int64_t aTextureId, TextureData* atextureData);
bool HandleExtensionEvent(int32_t aType);
@ -288,17 +269,10 @@ class CanvasTranslator final : public gfx::InlineTranslator,
bool CheckForFreshCanvasDevice(int aLineNumber);
void NotifyDeviceChanged();
bool EnsureSharedContextWebgl();
gfx::DrawTargetWebgl* GetDrawTargetWebgl(int64_t aTextureId) const;
void NotifyRequiresRefresh(int64_t aTextureId, bool aDispatch = true);
void CacheSnapshotShmem(int64_t aTextureId, bool aDispatch = true);
RefPtr<TaskQueue> mTranslationTaskQueue;
#if defined(XP_WIN)
RefPtr<ID3D11Device> mDevice;
#endif
RefPtr<gfx::SharedContextWebgl> mSharedContext;
RefPtr<RemoteTextureOwnerClient> mRemoteTextureOwner;
// We hold the ring buffer as a UniquePtr so we can drop it once
// mTranslationTaskQueue has shutdown to break a RefPtr cycle.
UniquePtr<CanvasEventRingBuffer> mStream;
@ -307,22 +281,13 @@ class CanvasTranslator final : public gfx::InlineTranslator,
// Sometimes during device reset our reference DrawTarget can be null, so we
// hold the BackendType separately.
gfx::BackendType mBackendType = gfx::BackendType::NONE;
struct TextureInfo {
UniquePtr<TextureData> mTextureData;
RefPtr<gfx::DrawTarget> mDrawTarget;
RemoteTextureOwnerId mRemoteTextureOwnerId;
bool mNotifiedRequiresRefresh = false;
// Ref-count of how active uses of the DT. Avoids deletion when locked.
int32_t mLocked = 1;
};
std::unordered_map<int64_t, TextureInfo> mTextureInfo;
typedef std::unordered_map<int64_t, UniquePtr<TextureData>> TextureMap;
TextureMap mTextureDatas;
int64_t mNextTextureId = -1;
RemoteTextureOwnerId mNextRemoteTextureOwnerId;
nsRefPtrHashtable<nsPtrHashKey<void>, gfx::DataSourceSurface> mDataSurfaces;
gfx::ReferencePtr mMappedSurface;
UniquePtr<gfx::DataSourceSurface::ScopedMap> mPreparedMap;
Atomic<bool> mDeactivated{false};
Atomic<bool> mBlocked{false};
bool mIsInTransaction = false;
bool mDeviceResetInProgress = false;
};

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

@ -516,7 +516,7 @@ PTextureChild* CompositorBridgeChild::CreateTexture(
}
already_AddRefed<CanvasChild> CompositorBridgeChild::GetCanvasChild() {
MOZ_ASSERT(gfxPlatform::UseRemoteCanvas());
MOZ_ASSERT(gfx::gfxVars::RemoteCanvasEnabled());
if (auto* cm = gfx::CanvasManagerChild::Get()) {
return cm->GetCanvasChild().forget();
}

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

@ -11,7 +11,6 @@ include "mozilla/layers/CanvasTranslator.h";
[MoveOnly] using mozilla::CrossProcessSemaphoreHandle from "mozilla/ipc/CrossProcessSemaphore.h";
using mozilla::layers::TextureType from "mozilla/layers/LayersTypes.h";
[MoveOnly] using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasic.h";
using mozilla::gfx::BackendType from "mozilla/gfx/Types.h";
namespace mozilla {
namespace layers {
@ -30,8 +29,7 @@ parent:
* memory handle for the ring buffer. aReaderSem and aWriterSem are handles
* for the semaphores to handle waiting on either side.
*/
async InitTranslator(TextureType aTextureType, BackendType aBackendType,
Handle aReadHandle,
async InitTranslator(TextureType aTextureType, Handle aReadHandle,
CrossProcessSemaphoreHandle aReaderSem,
CrossProcessSemaphoreHandle aWriterSem,
bool aUseIPDLThread);
@ -59,22 +57,6 @@ child:
* Deactivate remote canvas, which will cause fall back to software.
*/
async Deactivate();
/**
* Block further accelerated canvases from being created, but allow existing
* canvases to continue processing.
*/
async BlockCanvas();
/**
* Notify that a remote accelerated canvas requires a fallback refresh.
*/
async NotifyRequiresRefresh(int64_t aTextureId);
/**
* Cache the shmem of the framebuffer for snapshotting.
*/
async SnapshotShmem(int64_t aTextureId, Shmem aShmem) returns (bool aSuccess);
};
} // layers

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

@ -27,7 +27,7 @@ StaticAutoPtr<SharedSurfacesParent> SharedSurfacesParent::sInstance;
// Short wait to allow for a surface to be added, where the consumer has a
// different thread route.
static const TimeDuration kGetTimeout = TimeDuration::FromMilliseconds(1000);
static const TimeDuration kGetTimeout = TimeDuration::FromMilliseconds(50);
void SharedSurfacesParent::MappingTracker::NotifyExpiredLocked(
SourceSurfaceSharedDataWrapper* aSurface,
@ -95,7 +95,7 @@ void SharedSurfacesParent::Shutdown() {
/* static */
already_AddRefed<DataSourceSurface> SharedSurfacesParent::Get(
const wr::ExternalImageId& aId, bool aAllowWait) {
const wr::ExternalImageId& aId) {
StaticMonitorAutoLock lock(sMonitor);
if (!sInstance) {
gfxCriticalNote << "SSP:Get " << wr::AsUint64(aId) << " shtd";
@ -105,9 +105,6 @@ already_AddRefed<DataSourceSurface> SharedSurfacesParent::Get(
RefPtr<SourceSurfaceSharedDataWrapper> surface;
while (
!sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface))) {
if (!aAllowWait) {
return nullptr;
}
CVStatus status = lock.Wait(kGetTimeout);
if (status == CVStatus::Timeout) {
return nullptr;

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

@ -39,7 +39,7 @@ class SharedSurfacesParent final {
// Get without increasing the consumer count.
static already_AddRefed<gfx::DataSourceSurface> Get(
const wr::ExternalImageId& aId, bool aAllowWait = false);
const wr::ExternalImageId& aId);
// Get but also increase the consumer count. Must call Release after finished.
static already_AddRefed<gfx::DataSourceSurface> Acquire(

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

@ -143,7 +143,6 @@ void WebRenderImageHost::PushPendingRemoteTexture(
// Clear when RemoteTextureOwner is different.
mPendingRemoteTextureWrappers.clear();
mWaitingReadyCallback = false;
mWaitForRemoteTextureOwner = true;
}
}
@ -223,8 +222,7 @@ void WebRenderImageHost::UseRemoteTexture() {
std::function<void(const RemoteTextureInfo&)> function;
RemoteTextureMap::Get()->GetRemoteTextureForDisplayList(
wrapper, std::move(function), mWaitForRemoteTextureOwner);
mWaitForRemoteTextureOwner = false;
wrapper, std::move(function));
}
if (!texture ||

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

@ -88,7 +88,6 @@ class WebRenderImageHost : public CompositableHost, public ImageComposite {
std::deque<CompositableTextureHostRef> mPendingRemoteTextureWrappers;
bool mWaitingReadyCallback = false;
bool mWaitForRemoteTextureOwner = true;
Maybe<RemoteTextureOwnerId> mRemoteTextureOwnerIdOfPushCallback;
base::ProcessId mForPidOfPushCallback;

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

@ -1191,8 +1191,7 @@ bool gfxPlatform::IsHeadless() {
/* static */
bool gfxPlatform::UseRemoteCanvas() {
return XRE_IsContentProcess() && (gfx::gfxVars::RemoteCanvasEnabled() ||
gfx::gfxVars::UseAcceleratedCanvas2D());
return XRE_IsContentProcess() && gfx::gfxVars::RemoteCanvasEnabled();
}
/* static */
@ -3868,18 +3867,13 @@ void gfxPlatform::DisableGPUProcess() {
}
/* static */ void gfxPlatform::DisableRemoteCanvas() {
if (gfxVars::RemoteCanvasEnabled()) {
gfxConfig::ForceDisable(Feature::REMOTE_CANVAS, FeatureStatus::Failed,
"Disabled by runtime error",
"FEATURE_REMOTE_CANVAS_RUNTIME_ERROR"_ns);
gfxVars::SetRemoteCanvasEnabled(false);
}
if (gfxVars::UseAcceleratedCanvas2D()) {
gfxConfig::ForceDisable(Feature::ACCELERATED_CANVAS2D,
FeatureStatus::Failed, "Disabled by runtime error",
"FEATURE_ACCELERATED_CANVAS2D_RUNTIME_ERROR"_ns);
gfxVars::SetUseAcceleratedCanvas2D(false);
if (!gfxVars::RemoteCanvasEnabled()) {
return;
}
gfxConfig::ForceDisable(Feature::REMOTE_CANVAS, FeatureStatus::Failed,
"Disabled by runtime error",
"FEATURE_REMOTE_CANVAS_RUNTIME_ERROR"_ns);
gfxVars::SetRemoteCanvasEnabled(false);
}
void gfxPlatform::ImportCachedContentDeviceData() {

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

@ -104,7 +104,7 @@ fuzzy(0-1,0-43) == 1201272-1.html 1201272-1-ref.html
== 1303534-1.html 1303534-1-ref.html
fuzzy-if(cocoaWidget,0-1,0-1410) == 1304353-text-global-alpha-1.html 1304353-text-global-alpha-1-ref.html
fuzzy(0-1,0-1302) == 1304353-text-global-alpha-2.html 1304353-text-global-alpha-2-ref.html
fuzzy-if(cocoaWidget,0-1,0-1302) fuzzy-if(winWidget,0-1,0-578) == 1304353-text-global-alpha-2.html 1304353-text-global-alpha-2-ref.html
fuzzy-if(winWidget,0-94,0-1575) fuzzy-if(cocoaWidget,0-1,0-34) == 1304353-text-global-composite-op-1.html 1304353-text-global-composite-op-1-ref.html
== text-indent-1a.html text-indent-1-ref.html

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

@ -36,8 +36,8 @@ fails-if(useDrawSnapshot) == background-scale-with-viewbox-1.html background-sca
== canvas-drawImage-scale-1b.html lime100x100-ref.html
== canvas-drawImage-scale-1c.html lime100x100-ref.html
fuzzy(0-192,0-1813) == canvas-drawImage-scale-2a.html canvas-drawImage-scale-2-ref.html
fuzzy(0-192,0-1813) == canvas-drawImage-scale-2b.html canvas-drawImage-scale-2-ref.html
fuzzy(0-1,0-2) fuzzy-if(!remoteCanvas,0-1,0-529) fuzzy-if(remoteCanvas,0-97,0-745) fuzzy-if(Android&&device,0-64,0-1212) == canvas-drawImage-scale-2a.html canvas-drawImage-scale-2-ref.html
fuzzy(0-1,0-2) fuzzy-if(!remoteCanvas,0-1,0-529) fuzzy-if(remoteCanvas,0-97,0-745) fuzzy-if(Android&&device,0-64,0-1212) == canvas-drawImage-scale-2b.html canvas-drawImage-scale-2-ref.html
fuzzy-if(winWidget,0-1,0-10000) fuzzy-if(azureSkia,0-1,0-10000) fuzzy-if(Android,0-1,0-10000) == canvas-drawImage-alpha-1.html canvas-drawImage-alpha-1-ref.html
#Same as scale-2a but with globalAlpha:

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

@ -2,6 +2,6 @@
# e.g. filter: blur(3px) grayscale(0.5) invert(0.2);
# Some platforms render this complex filter chain a little differently, and that's ok.
fuzzy(4-10,12000-20260) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
fuzzy(4-6,12000-19950) fuzzy-if(swgl,5-10,13600-20260) fuzzy-if(Android&&device&&!swgl,6-6,19986-19986) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
== moz-element.html moz-element-ref.html
fuzzy(0-15,0-14056) == same-filter.html same-filter-ref.html
fuzzy-if(!useDrawSnapshot,13-15,7670-7982) fuzzy-if(!useDrawSnapshot&&swgl,11-12,14052-14056) fuzzy-if(Android&&device&&!swgl,13-13,13505-13505) == same-filter.html same-filter-ref.html

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

@ -5622,13 +5622,13 @@
mirror: always
- name: gfx.canvas.accelerated.max-draw-target-count
type: RelaxedAtomicUint32
type: RelaxedAtomicInt32
value: 200
mirror: always
- name: gfx.canvas.accelerated.max-size
type: RelaxedAtomicInt32
value: 8192
value: 0
mirror: always
- name: gfx.canvas.accelerated.min-size