зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1478815 part 9 - Add ability to create a DrawTargetCapture that can flush to its destination draw target. r=bas
This commit adds the ability to create a different kind of DrawTargetCapture which has a limit on the size of which its CaptureCommandList can grow before it is synchronously flushed to its destination DrawTarget. Special care is taken to not do a sync flush until we would need to resize the backing store of the CaptureCommandList. This allows us to not waste memory we've already allocated. The async painting content clients are updated to use it, and get a default value from a new preference. MozReview-Commit-ID: CJL7ffvaRzR --HG-- extra : rebase_source : 546d9838808320c51d9ceef0ed0ffcbb88a16269
This commit is contained in:
Родитель
af49011c30
Коммит
8b6aa26413
12
gfx/2d/2D.h
12
gfx/2d/2D.h
|
@ -1632,6 +1632,18 @@ public:
|
|||
static already_AddRefed<DrawTarget>
|
||||
CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFormat aFormat);
|
||||
|
||||
/**
|
||||
* Create a DrawTarget that captures the drawing commands to eventually be replayed
|
||||
* onto the DrawTarget provided. An optional byte size can be provided as a limit
|
||||
* for the CaptureCommandList. When the limit is reached, the CaptureCommandList
|
||||
* will be replayed to the target and then cleared.
|
||||
*
|
||||
* @param aSize Size of the area this DT will capture.
|
||||
* @param aFlushBytes The byte limit at which to flush the CaptureCommandList
|
||||
*/
|
||||
static already_AddRefed<DrawTargetCapture>
|
||||
CreateCaptureDrawTargetForTarget(gfx::DrawTarget* aTarget, size_t aFlushBytes = 0);
|
||||
|
||||
/**
|
||||
* Create a DrawTarget that captures the drawing commands and can be replayed
|
||||
* onto a compatible DrawTarget afterwards.
|
||||
|
|
|
@ -11,11 +11,19 @@ namespace mozilla {
|
|||
namespace gfx {
|
||||
|
||||
CaptureCommandList::~CaptureCommandList()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void
|
||||
CaptureCommandList::Clear()
|
||||
{
|
||||
for (iterator iter(*this); !iter.Done(); iter.Next()) {
|
||||
DrawingCommand* cmd = iter.Get();
|
||||
cmd->~DrawingCommand();
|
||||
}
|
||||
mLastCommand = nullptr;
|
||||
mStorage.clear();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -64,6 +64,17 @@ public:
|
|||
return Append<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool BufferWillAlloc() const {
|
||||
return mStorage.size() + sizeof(uint32_t) + sizeof(T) > mStorage.capacity();
|
||||
}
|
||||
|
||||
size_t BufferCapacity() const {
|
||||
return mStorage.capacity();
|
||||
}
|
||||
|
||||
void Clear();
|
||||
|
||||
class iterator
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -23,13 +23,27 @@ DrawTargetCaptureImpl::~DrawTargetCaptureImpl()
|
|||
}
|
||||
}
|
||||
|
||||
DrawTargetCaptureImpl::DrawTargetCaptureImpl(gfx::DrawTarget* aTarget, size_t aFlushBytes)
|
||||
: mSnapshot(nullptr),
|
||||
mStride(0),
|
||||
mSurfaceAllocationSize(0),
|
||||
mFlushBytes(aFlushBytes)
|
||||
{
|
||||
mSize = aTarget->GetSize();
|
||||
mFormat = aTarget->GetFormat();
|
||||
SetPermitSubpixelAA(aTarget->GetPermitSubpixelAA());
|
||||
|
||||
mRefDT = aTarget;
|
||||
}
|
||||
|
||||
DrawTargetCaptureImpl::DrawTargetCaptureImpl(BackendType aBackend,
|
||||
const IntSize& aSize,
|
||||
SurfaceFormat aFormat)
|
||||
: mSize(aSize),
|
||||
mSnapshot(nullptr),
|
||||
mStride(0),
|
||||
mSurfaceAllocationSize(0)
|
||||
mSurfaceAllocationSize(0),
|
||||
mFlushBytes(0)
|
||||
{
|
||||
RefPtr<DrawTarget> screenRefDT =
|
||||
gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget();
|
||||
|
@ -75,6 +89,7 @@ DrawTargetCaptureImpl::Init(const IntSize& aSize, DrawTarget* aRefDT)
|
|||
void
|
||||
DrawTargetCaptureImpl::InitForData(int32_t aStride, size_t aSurfaceAllocationSize)
|
||||
{
|
||||
MOZ_ASSERT(!mFlushBytes);
|
||||
mStride = aStride;
|
||||
mSurfaceAllocationSize = aSurfaceAllocationSize;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ class DrawTargetCaptureImpl : public DrawTargetCapture
|
|||
friend class SourceSurfaceCapture;
|
||||
|
||||
public:
|
||||
DrawTargetCaptureImpl(gfx::DrawTarget* aTarget, size_t aFlushBytes);
|
||||
DrawTargetCaptureImpl(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat);
|
||||
|
||||
bool Init(const IntSize& aSize, DrawTarget* aRefDT);
|
||||
|
@ -156,6 +157,12 @@ protected:
|
|||
void MarkChanged();
|
||||
|
||||
private:
|
||||
void FlushCommandBuffer()
|
||||
{
|
||||
ReplayToDrawTarget(mRefDT, Matrix());
|
||||
mCommands.Clear();
|
||||
}
|
||||
|
||||
// This storage system was used to minimize the amount of heap allocations
|
||||
// that are required while recording. It should be noted there's no
|
||||
// guarantees on the alignments of DrawingCommands allocated in this array.
|
||||
|
@ -164,6 +171,11 @@ private:
|
|||
if (T::AffectsSnapshot) {
|
||||
MarkChanged();
|
||||
}
|
||||
if (mFlushBytes &&
|
||||
mCommands.BufferWillAlloc<T>() &&
|
||||
mCommands.BufferCapacity() > mFlushBytes) {
|
||||
FlushCommandBuffer();
|
||||
}
|
||||
return mCommands.Append<T>();
|
||||
}
|
||||
template<typename T>
|
||||
|
@ -171,6 +183,11 @@ private:
|
|||
if (T::AffectsSnapshot) {
|
||||
MarkChanged();
|
||||
}
|
||||
if (mFlushBytes &&
|
||||
mCommands.BufferWillAlloc<T>() &&
|
||||
mCommands.BufferCapacity() > mFlushBytes) {
|
||||
FlushCommandBuffer();
|
||||
}
|
||||
return mCommands.ReuseOrAppend<T>();
|
||||
}
|
||||
|
||||
|
@ -192,6 +209,7 @@ private:
|
|||
std::vector<PushedLayer> mPushedLayers;
|
||||
|
||||
CaptureCommandList mCommands;
|
||||
size_t mFlushBytes;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
|
|
|
@ -451,6 +451,12 @@ Factory::CreateRecordingDrawTarget(DrawEventRecorder *aRecorder, DrawTarget *aDT
|
|||
return MakeAndAddRef<DrawTargetRecording>(aRecorder, aDT, aSize);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTargetCapture>
|
||||
Factory::CreateCaptureDrawTargetForTarget(gfx::DrawTarget* aTarget, size_t aFlushBytes)
|
||||
{
|
||||
return MakeAndAddRef<DrawTargetCaptureImpl>(aTarget, aFlushBytes);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTargetCapture>
|
||||
Factory::CreateCaptureDrawTarget(BackendType aBackend, const IntSize& aSize, SurfaceFormat aFormat)
|
||||
{
|
||||
|
|
|
@ -83,10 +83,7 @@ RotatedBuffer::BeginCapture()
|
|||
|
||||
MOZ_ASSERT(!mCapture);
|
||||
MOZ_ASSERT(target);
|
||||
mCapture =
|
||||
Factory::CreateCaptureDrawTarget(target->GetBackendType(),
|
||||
target->GetSize(),
|
||||
target->GetFormat());
|
||||
mCapture = Factory::CreateCaptureDrawTargetForTarget(target, gfxPrefs::LayersOMTPCaptureLimit());
|
||||
}
|
||||
|
||||
RefPtr<gfx::DrawTargetCapture>
|
||||
|
|
|
@ -711,10 +711,7 @@ TileClient::AcquireBackBuffer(CompositableClient& aCompositable,
|
|||
// Construct a capture draw target if necessary
|
||||
RefPtr<DrawTargetCapture> capture;
|
||||
if (aFlags & TilePaintFlags::Async) {
|
||||
capture =
|
||||
Factory::CreateCaptureDrawTarget(target->GetBackendType(),
|
||||
target->GetSize(),
|
||||
target->GetFormat());
|
||||
capture = Factory::CreateCaptureDrawTargetForTarget(target, gfxPrefs::LayersOMTPCaptureLimit());
|
||||
target = capture;
|
||||
}
|
||||
|
||||
|
|
|
@ -634,6 +634,7 @@ private:
|
|||
DECL_GFX_PREF(Once, "layers.mlgpu.enable-container-resizing", AdvancedLayersEnableContainerResizing, bool, true);
|
||||
DECL_GFX_PREF(Once, "layers.offmainthreadcomposition.force-disabled", LayersOffMainThreadCompositionForceDisabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "layers.offmainthreadcomposition.frame-rate", LayersCompositionFrameRate, int32_t,-1);
|
||||
DECL_GFX_PREF(Once, "layers.omtp.capture-limit", LayersOMTPCaptureLimit, uint32_t, 25 * 1024 * 1024);
|
||||
DECL_GFX_PREF(Live, "layers.omtp.dump-capture", LayersOMTPDumpCapture, bool, false);
|
||||
DECL_GFX_PREF(Once, "layers.omtp.paint-workers", LayersOMTPPaintWorkers, int32_t, 1);
|
||||
DECL_GFX_PREF(Live, "layers.omtp.release-capture-on-main-thread", LayersOMTPReleaseCaptureOnMainThread, bool, false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче