Cache the command buffer objects

Change-Id: I35bc1fab8ed6b72baf75d2e4271a040e0209440d
Reviewed-on: https://skia-review.googlesource.com/145821
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Robert Phillips 2018-08-09 15:12:18 -04:00 committed by Skia Commit-Bot
parent e9f66b26b1
commit 5b5d84cc1f
19 changed files with 236 additions and 141 deletions

View File

@ -239,16 +239,16 @@ public:
const SkIPoint& dstPoint,
bool canDiscardOutsideDstRect = false);
// Creates a GrGpuRTCommandBuffer which GrOpLists send draw commands to instead of directly
// Returns a GrGpuRTCommandBuffer which GrOpLists send draw commands to instead of directly
// to the Gpu object.
virtual GrGpuRTCommandBuffer* createCommandBuffer(
virtual GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) = 0;
// Creates a GrGpuTextureCommandBuffer which GrOpLists send texture commands to instead of
// Returns a GrGpuTextureCommandBuffer which GrOpLists send texture commands to instead of
// directly to the Gpu object.
virtual GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) = 0;
virtual GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) = 0;
// Called by GrDrawingManager when flushing.
// Provides a hook for post-flush actions (e.g. Vulkan command buffer submits). This will also
@ -256,6 +256,8 @@ public:
// inserted semaphores.
GrSemaphoresSubmitted finishFlush(int numSemaphores, GrBackendSemaphore backendSemaphores[]);
virtual void submit(GrGpuCommandBuffer*) = 0;
virtual GrFence SK_WARN_UNUSED_RESULT insertFence() = 0;
virtual bool waitFence(GrFence, uint64_t timeout = 1000) = 0;
virtual void deleteFence(GrFence) const = 0;

View File

@ -36,29 +36,27 @@ public:
virtual void insertEventMarker(const char*) = 0;
virtual GrGpuRTCommandBuffer* asRTCommandBuffer() { return nullptr; }
// Sends the command buffer off to the GPU object to execute the commands built up in the
// buffer. The gpu object is allowed to defer execution of the commands until it is flushed.
virtual void submit() = 0;
protected:
GrGpuCommandBuffer(GrSurfaceOrigin origin) : fOrigin(origin) {}
GrSurfaceOrigin fOrigin;
};
class GrGpuTextureCommandBuffer : public GrGpuCommandBuffer{
public:
virtual ~GrGpuTextureCommandBuffer() {}
void set(GrTexture* texture, GrSurfaceOrigin origin) {
SkASSERT(!fTexture);
virtual void submit() = 0;
fOrigin = origin;
fTexture = texture;
}
protected:
GrGpuTextureCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin)
: INHERITED(origin)
, fTexture(texture) {}
GrGpuTextureCommandBuffer() : fOrigin(kTopLeft_GrSurfaceOrigin), fTexture(nullptr) {}
GrTexture* fTexture;
GrGpuTextureCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin)
: fOrigin(origin)
, fTexture(texture) {
}
GrSurfaceOrigin fOrigin;
GrTexture* fTexture;
private:
typedef GrGpuCommandBuffer INHERITED;
@ -85,8 +83,6 @@ public:
GrStoreOp fStoreOp;
};
virtual ~GrGpuRTCommandBuffer() {}
GrGpuRTCommandBuffer* asRTCommandBuffer() { return this; }
virtual void begin() = 0;
@ -122,11 +118,21 @@ public:
virtual void discard() = 0;
protected:
GrGpuRTCommandBuffer() : fOrigin(kTopLeft_GrSurfaceOrigin), fRenderTarget(nullptr) {}
GrGpuRTCommandBuffer(GrRenderTarget* rt, GrSurfaceOrigin origin)
: INHERITED(origin)
: fOrigin(origin)
, fRenderTarget(rt) {
}
void set(GrRenderTarget* rt, GrSurfaceOrigin origin) {
SkASSERT(!fRenderTarget);
fRenderTarget = rt;
fOrigin = origin;
}
GrSurfaceOrigin fOrigin;
GrRenderTarget* fRenderTarget;
private:

View File

@ -183,6 +183,11 @@ bool GrOpList::isFullyInstantiated() const {
}
}
GrSurface* surface = proxy->peekSurface();
if (surface->wasDestroyed()) {
return false;
}
return true;
}

View File

@ -107,12 +107,12 @@ void GrRenderTargetOpList::onPrepare(GrOpFlushState* flushState) {
}
}
static std::unique_ptr<GrGpuRTCommandBuffer> create_command_buffer(GrGpu* gpu,
GrRenderTarget* rt,
GrSurfaceOrigin origin,
GrLoadOp colorLoadOp,
GrColor loadClearColor,
GrLoadOp stencilLoadOp) {
static GrGpuRTCommandBuffer* create_command_buffer(GrGpu* gpu,
GrRenderTarget* rt,
GrSurfaceOrigin origin,
GrLoadOp colorLoadOp,
GrColor loadClearColor,
GrLoadOp stencilLoadOp) {
const GrGpuRTCommandBuffer::LoadAndStoreInfo kColorLoadStoreInfo {
colorLoadOp,
GrStoreOp::kStore,
@ -129,20 +129,7 @@ static std::unique_ptr<GrGpuRTCommandBuffer> create_command_buffer(GrGpu* gpu,
GrStoreOp::kStore,
};
std::unique_ptr<GrGpuRTCommandBuffer> buffer(
gpu->createCommandBuffer(rt, origin,
kColorLoadStoreInfo,
stencilLoadAndStoreInfo));
return buffer;
}
static inline void finish_command_buffer(GrGpuRTCommandBuffer* buffer) {
if (!buffer) {
return;
}
buffer->end();
buffer->submit();
return gpu->getCommandBuffer(rt, origin, kColorLoadStoreInfo, stencilLoadAndStoreInfo);
}
// TODO: this is where GrOp::renderTarget is used (which is fine since it
@ -165,14 +152,14 @@ bool GrRenderTargetOpList::onExecute(GrOpFlushState* flushState) {
// TODO: at the very least, we want the stencil store op to always be discard (at this
// level). In Vulkan, sub-command buffers would still need to load & store the stencil buffer.
std::unique_ptr<GrGpuRTCommandBuffer> commandBuffer = create_command_buffer(
GrGpuRTCommandBuffer* commandBuffer = create_command_buffer(
flushState->gpu(),
fTarget.get()->peekRenderTarget(),
fTarget.get()->origin(),
fColorLoadOp,
fLoadClearColor,
fStencilLoadOp);
flushState->setCommandBuffer(commandBuffer.get());
flushState->setCommandBuffer(commandBuffer);
commandBuffer->begin();
// Draw all the generated geometry.
@ -196,7 +183,8 @@ bool GrRenderTargetOpList::onExecute(GrOpFlushState* flushState) {
flushState->setOpArgs(nullptr);
}
finish_command_buffer(commandBuffer.get());
commandBuffer->end();
flushState->gpu()->submit(commandBuffer);
flushState->setCommandBuffer(nullptr);
return true;

View File

@ -99,10 +99,10 @@ bool GrTextureOpList::onExecute(GrOpFlushState* flushState) {
SkASSERT(fTarget.get()->peekTexture());
std::unique_ptr<GrGpuTextureCommandBuffer> commandBuffer(
flushState->gpu()->createCommandBuffer(fTarget.get()->peekTexture(),
fTarget.get()->origin()));
flushState->setCommandBuffer(commandBuffer.get());
GrGpuTextureCommandBuffer* commandBuffer(
flushState->gpu()->getCommandBuffer(fTarget.get()->peekTexture(),
fTarget.get()->origin()));
flushState->setCommandBuffer(commandBuffer);
for (int i = 0; i < fRecordedOps.count(); ++i) {
if (!fRecordedOps[i]) {
@ -120,7 +120,7 @@ bool GrTextureOpList::onExecute(GrOpFlushState* flushState) {
flushState->setOpArgs(nullptr);
}
commandBuffer->submit();
flushState->gpu()->submit(commandBuffer);
flushState->setCommandBuffer(nullptr);
return true;

View File

@ -2156,16 +2156,25 @@ bool GrGLGpu::onReadPixels(GrSurface* surface, int left, int top, int width, int
return true;
}
GrGpuRTCommandBuffer* GrGLGpu::createCommandBuffer(
GrGpuRTCommandBuffer* GrGLGpu::getCommandBuffer(
GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
return new GrGLGpuRTCommandBuffer(this, rt, origin, colorInfo, stencilInfo);
if (!fCachedRTCommandBuffer) {
fCachedRTCommandBuffer.reset(new GrGLGpuRTCommandBuffer(this));
}
fCachedRTCommandBuffer->set(rt, origin, colorInfo, stencilInfo);
return fCachedRTCommandBuffer.get();
}
GrGpuTextureCommandBuffer* GrGLGpu::createCommandBuffer(GrTexture* texture,
GrSurfaceOrigin origin) {
return new GrGLGpuTextureCommandBuffer(this, texture, origin);
GrGpuTextureCommandBuffer* GrGLGpu::getCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) {
if (!fCachedTexCommandBuffer) {
fCachedTexCommandBuffer.reset(new GrGLGpuTextureCommandBuffer(this));
}
fCachedTexCommandBuffer->set(texture, origin);
return fCachedTexCommandBuffer.get();
}
void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, GrSurfaceOrigin origin,
@ -4115,6 +4124,16 @@ void GrGLGpu::onFinishFlush(bool insertedSemaphore) {
}
}
void GrGLGpu::submit(GrGpuCommandBuffer* buffer) {
if (buffer->asRTCommandBuffer()) {
SkASSERT(fCachedRTCommandBuffer.get() == buffer);
fCachedRTCommandBuffer->reset();
} else {
SkASSERT(fCachedTexCommandBuffer.get() == buffer);
fCachedTexCommandBuffer->reset();
}
}
GrFence SK_WARN_UNUSED_RESULT GrGLGpu::insertFence() {
SkASSERT(this->caps()->fenceSyncSupport());
GrGLsync sync;

View File

@ -25,6 +25,8 @@
#include "SkTypes.h"
class GrGLBuffer;
class GrGLGpuRTCommandBuffer;
class GrGLGpuTextureCommandBuffer;
class GrPipeline;
class GrSwizzle;
@ -118,12 +120,12 @@ public:
void clearStencil(GrRenderTarget*, int clearValue) override;
GrGpuRTCommandBuffer* createCommandBuffer(
GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
void invalidateBoundRenderTarget() {
fHWBoundRenderTargetUniqueID.makeInvalid();
@ -150,6 +152,8 @@ public:
void testingOnly_flushGpuAndSync() override;
#endif
void submit(GrGpuCommandBuffer* buffer) override;
GrFence SK_WARN_UNUSED_RESULT insertFence() override;
bool waitFence(GrFence, uint64_t timeout) override;
void deleteFence(GrFence) const override;
@ -566,7 +570,7 @@ private:
}
} fHWBlendState;
TriState fMSAAEnabled;
TriState fMSAAEnabled;
GrStencilSettings fHWStencilSettings;
TriState fHWStencilTestEnabled;
@ -623,8 +627,12 @@ private:
GrPrimitiveType fLastPrimitiveType;
bool fRequiresFlushBeforeNextInstancedDraw = false;
typedef GrGpu INHERITED;
std::unique_ptr<GrGLGpuRTCommandBuffer> fCachedRTCommandBuffer;
std::unique_ptr<GrGLGpuTextureCommandBuffer> fCachedTexCommandBuffer;
friend class GrGLPathRendering; // For accessing setTextureUnit.
typedef GrGpu INHERITED;
};
#endif

View File

@ -22,3 +22,15 @@ void GrGLGpuRTCommandBuffer::begin() {
}
}
}
void GrGLGpuRTCommandBuffer::set(GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
SkASSERT(fGpu);
SkASSERT(!fRenderTarget);
SkASSERT(fGpu == rt->getContext()->contextPriv().getGpu());
this->INHERITED::set(rt, origin);
fColorLoadAndStoreInfo = colorInfo;
fStencilLoadAndStoreInfo = stencilInfo;
}

View File

@ -19,14 +19,7 @@ class GrGLRenderTarget;
class GrGLGpuTextureCommandBuffer : public GrGpuTextureCommandBuffer {
public:
GrGLGpuTextureCommandBuffer(GrGLGpu* gpu, GrTexture* texture, GrSurfaceOrigin origin)
: INHERITED(texture, origin)
, fGpu(gpu) {
}
~GrGLGpuTextureCommandBuffer() override {}
void submit() override {}
GrGLGpuTextureCommandBuffer(GrGLGpu* gpu) : fGpu(gpu) {}
void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
const SkIPoint& dstPoint) override {
@ -37,6 +30,10 @@ public:
fGpu->insertEventMarker(msg);
}
void reset() {
fTexture = nullptr;
}
private:
GrGLGpu* fGpu;
@ -50,16 +47,7 @@ class GrGLGpuRTCommandBuffer : public GrGpuRTCommandBuffer {
* pass through functions to corresponding calls in the GrGLGpu class.
*/
public:
GrGLGpuRTCommandBuffer(GrGLGpu* gpu, GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo)
: INHERITED(rt, origin)
, fGpu(gpu)
, fColorLoadAndStoreInfo(colorInfo)
, fStencilLoadAndStoreInfo(stencilInfo) {
}
~GrGLGpuRTCommandBuffer() override {}
GrGLGpuRTCommandBuffer(GrGLGpu* gpu) : fGpu(gpu) {}
void begin() override;
void end() override {}
@ -79,7 +67,13 @@ public:
fGpu->copySurface(fRenderTarget, fOrigin, src, srcOrigin, srcRect, dstPoint);
}
void submit() override {}
void set(GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&);
void reset() {
fRenderTarget = nullptr;
}
private:
GrGpu* gpu() override { return fGpu; }

View File

@ -47,19 +47,25 @@ sk_sp<GrGpu> GrMockGpu::Make(const GrMockOptions* mockOptions,
return sk_sp<GrGpu>(new GrMockGpu(context, *mockOptions, contextOptions));
}
GrGpuRTCommandBuffer* GrMockGpu::createCommandBuffer(
GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) {
GrGpuRTCommandBuffer* GrMockGpu::getCommandBuffer(
GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) {
return new GrMockGpuRTCommandBuffer(this, rt, origin);
}
GrGpuTextureCommandBuffer* GrMockGpu::createCommandBuffer(GrTexture* texture,
GrSurfaceOrigin origin) {
GrGpuTextureCommandBuffer* GrMockGpu::getCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) {
return new GrMockGpuTextureCommandBuffer(texture, origin);
}
void GrMockGpu::submit(GrGpuCommandBuffer* buffer) {
if (buffer->asRTCommandBuffer()) {
this->submitCommandBuffer(
static_cast<GrMockGpuRTCommandBuffer*>(buffer->asRTCommandBuffer()));
}
delete buffer;
}
void GrMockGpu::submitCommandBuffer(const GrMockGpuRTCommandBuffer* cmdBuffer) {
for (int i = 0; i < cmdBuffer->numDraws(); ++i) {

View File

@ -24,12 +24,12 @@ public:
~GrMockGpu() override {}
GrGpuRTCommandBuffer* createCommandBuffer(
GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
bool waitFence(GrFence, uint64_t) override { return true; }
@ -45,11 +45,13 @@ public:
void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
void submitCommandBuffer(const GrMockGpuRTCommandBuffer*);
void submit(GrGpuCommandBuffer* buffer) override;
private:
GrMockGpu(GrContext* context, const GrMockOptions&, const GrContextOptions&);
void submitCommandBuffer(const GrMockGpuRTCommandBuffer*);
void onResetContext(uint32_t resetBits) override {}
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}

View File

@ -24,8 +24,6 @@ public:
void insertEventMarker(const char*) override {}
private:
void submit() override {}
typedef GrGpuTextureCommandBuffer INHERITED;
};
@ -47,8 +45,6 @@ public:
int numDraws() const { return fNumDraws; }
void submit() override { fGpu->submitCommandBuffer(this); }
private:
void onDraw(const GrPrimitiveProcessor&, const GrPipeline&,
const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*,

View File

@ -85,15 +85,17 @@ public:
const SkIPoint& dstPoint,
bool canDiscardOutsideDstRect) override;
GrGpuRTCommandBuffer* createCommandBuffer(
GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
SkSL::Compiler* shaderCompiler() const { return fCompiler.get(); }
void submit(GrGpuCommandBuffer* buffer) override;
GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
bool waitFence(GrFence, uint64_t) override { return true; }
void deleteFence(GrFence) const override {}

View File

@ -105,18 +105,22 @@ GrMtlGpu::GrMtlGpu(GrContext* context, const GrContextOptions& options,
fCmdBuffer = [fQueue commandBuffer];
}
GrGpuRTCommandBuffer* GrMtlGpu::createCommandBuffer(
GrGpuRTCommandBuffer* GrMtlGpu::getCommandBuffer(
GrRenderTarget* renderTarget, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
return new GrMtlGpuRTCommandBuffer(this, renderTarget, origin, colorInfo, stencilInfo);
}
GrGpuTextureCommandBuffer* GrMtlGpu::createCommandBuffer(GrTexture* texture,
GrSurfaceOrigin origin) {
GrGpuTextureCommandBuffer* GrMtlGpu::getCommandBuffer(GrTexture* texture,
GrSurfaceOrigin origin) {
return new GrMtlGpuTextureCommandBuffer(this, texture, origin);
}
void GrMtlGpu::submit(GrGpuCommandBuffer* buffer) {
delete buffer;
}
void GrMtlGpu::submitCommandBuffer(SyncQueue sync) {
SkASSERT(fCmdBuffer);
[fCmdBuffer commit];
@ -768,3 +772,4 @@ bool GrMtlGpu::onReadPixels(GrSurface* surface, int left, int top, int width, in
SkRectMemcpy(buffer, rowBytes, mappedMemory, transBufferRowBytes, transBufferRowBytes, height);
return true;
}

View File

@ -32,8 +32,6 @@ public:
void insertEventMarker(const char* msg) override {}
private:
void submit() override {}
GrMtlGpu* fGpu;
typedef GrGpuTextureCommandBuffer INHERITED;
@ -53,8 +51,6 @@ public:
(void)fStencilLoadAndStoreInfo;
}
~GrMtlGpuRTCommandBuffer() override {}
void begin() override {}
void end() override {}
@ -69,8 +65,6 @@ public:
fGpu->copySurface(fRenderTarget, fOrigin, src, srcOrigin, srcRect, dstPoint);
}
void submit() override {}
private:
GrGpu* gpu() override { return fGpu; }

View File

@ -274,16 +274,25 @@ void GrVkGpu::disconnect(DisconnectType type) {
///////////////////////////////////////////////////////////////////////////////
GrGpuRTCommandBuffer* GrVkGpu::createCommandBuffer(
GrGpuRTCommandBuffer* GrVkGpu::getCommandBuffer(
GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
return new GrVkGpuRTCommandBuffer(this, rt, origin, colorInfo, stencilInfo);
if (!fCachedRTCommandBuffer) {
fCachedRTCommandBuffer.reset(new GrVkGpuRTCommandBuffer(this));
}
fCachedRTCommandBuffer->set(rt, origin, colorInfo, stencilInfo);
return fCachedRTCommandBuffer.get();
}
GrGpuTextureCommandBuffer* GrVkGpu::createCommandBuffer(GrTexture* texture,
GrSurfaceOrigin origin) {
return new GrVkGpuTextureCommandBuffer(this, texture, origin);
GrGpuTextureCommandBuffer* GrVkGpu::getCommandBuffer(GrTexture* texture, GrSurfaceOrigin origin) {
if (!fCachedTexCommandBuffer) {
fCachedTexCommandBuffer.reset(new GrVkGpuTextureCommandBuffer(this));
}
fCachedTexCommandBuffer->set(texture, origin);
return fCachedTexCommandBuffer.get();
}
void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
@ -1954,6 +1963,20 @@ void GrVkGpu::submitSecondaryCommandBuffer(const SkTArray<GrVkSecondaryCommandBu
this->didWriteToSurface(target, origin, &bounds);
}
void GrVkGpu::submit(GrGpuCommandBuffer* buffer) {
if (buffer->asRTCommandBuffer()) {
SkASSERT(fCachedRTCommandBuffer.get() == buffer);
fCachedRTCommandBuffer->submit();
fCachedRTCommandBuffer->reset();
} else {
SkASSERT(fCachedTexCommandBuffer.get() == buffer);
fCachedTexCommandBuffer->submit();
fCachedTexCommandBuffer->reset();
}
}
GrFence SK_WARN_UNUSED_RESULT GrVkGpu::insertFence() {
VkFenceCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkFenceCreateInfo));

View File

@ -23,6 +23,8 @@
class GrPipeline;
class GrVkBufferImpl;
class GrVkGpuRTCommandBuffer;
class GrVkGpuTextureCommandBuffer;
class GrVkMemoryAllocator;
class GrVkPipeline;
class GrVkPipelineState;
@ -89,12 +91,13 @@ public:
void clearStencil(GrRenderTarget* target, int clearValue) override;
GrGpuRTCommandBuffer* createCommandBuffer(
GrGpuRTCommandBuffer* getCommandBuffer(
GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&) override;
GrGpuTextureCommandBuffer* createCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
GrGpuTextureCommandBuffer* getCommandBuffer(GrTexture*, GrSurfaceOrigin) override;
void addMemoryBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
@ -125,6 +128,8 @@ public:
GrVkRenderTarget*, GrSurfaceOrigin,
const SkIRect& bounds);
void submit(GrGpuCommandBuffer*) override;
GrFence SK_WARN_UNUSED_RESULT insertFence() override;
bool waitFence(GrFence, uint64_t timeout) override;
void deleteFence(GrFence) const override;
@ -252,6 +257,9 @@ private:
// vulkan context.
bool fDisconnected;
std::unique_ptr<GrVkGpuRTCommandBuffer> fCachedRTCommandBuffer;
std::unique_ptr<GrVkGpuTextureCommandBuffer> fCachedTexCommandBuffer;
typedef GrGpu INHERITED;
};

View File

@ -73,22 +73,10 @@ void get_vk_load_store_ops(GrLoadOp loadOpIn, GrStoreOp storeOpIn,
}
}
GrVkGpuRTCommandBuffer::GrVkGpuRTCommandBuffer(GrVkGpu* gpu,
GrRenderTarget* rt, GrSurfaceOrigin origin,
const LoadAndStoreInfo& colorInfo,
const StencilLoadAndStoreInfo& stencilInfo)
: INHERITED(rt, origin)
GrVkGpuRTCommandBuffer::GrVkGpuRTCommandBuffer(GrVkGpu* gpu)
: fCurrentCmdInfo(-1)
, fGpu(gpu)
, fClearColor(GrColor4f::FromGrColor(colorInfo.fClearColor))
, fLastPipelineState(nullptr) {
get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
&fVkColorLoadOp, &fVkColorStoreOp);
get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
&fVkStencilLoadOp, &fVkStencilStoreOp);
fCurrentCmdInfo = -1;
this->init();
}
void GrVkGpuRTCommandBuffer::init() {
@ -137,13 +125,7 @@ void GrVkGpuRTCommandBuffer::init() {
GrVkGpuRTCommandBuffer::~GrVkGpuRTCommandBuffer() {
for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
cbInfo.fCommandBuffers[j]->unref(fGpu);
}
cbInfo.fRenderPass->unref(fGpu);
}
this->reset();
}
GrGpu* GrVkGpuRTCommandBuffer::gpu() { return fGpu; }
@ -241,6 +223,44 @@ void GrVkGpuRTCommandBuffer::submit() {
}
}
void GrVkGpuRTCommandBuffer::set(GrRenderTarget* rt, GrSurfaceOrigin origin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo& stencilInfo) {
SkASSERT(!fRenderTarget);
SkASSERT(fCommandBufferInfos.empty());
SkASSERT(-1 == fCurrentCmdInfo);
SkASSERT(fGpu == rt->getContext()->contextPriv().getGpu());
SkASSERT(!fLastPipelineState);
this->INHERITED::set(rt, origin);
fClearColor = GrColor4f::FromGrColor(colorInfo.fClearColor);
get_vk_load_store_ops(colorInfo.fLoadOp, colorInfo.fStoreOp,
&fVkColorLoadOp, &fVkColorStoreOp);
get_vk_load_store_ops(stencilInfo.fLoadOp, stencilInfo.fStoreOp,
&fVkStencilLoadOp, &fVkStencilStoreOp);
this->init();
}
void GrVkGpuRTCommandBuffer::reset() {
for (int i = 0; i < fCommandBufferInfos.count(); ++i) {
CommandBufferInfo& cbInfo = fCommandBufferInfos[i];
for (int j = 0; j < cbInfo.fCommandBuffers.count(); ++j) {
cbInfo.fCommandBuffers[j]->unref(fGpu);
}
cbInfo.fRenderPass->unref(fGpu);
}
fCommandBufferInfos.reset();
fCurrentCmdInfo = -1;
fLastPipelineState = nullptr;
fRenderTarget = nullptr;
}
void GrVkGpuRTCommandBuffer::discard() {
GrVkRenderTarget* vkRT = static_cast<GrVkRenderTarget*>(fRenderTarget);

View File

@ -23,10 +23,7 @@ class GrVkSecondaryCommandBuffer;
class GrVkGpuTextureCommandBuffer : public GrGpuTextureCommandBuffer {
public:
GrVkGpuTextureCommandBuffer(GrVkGpu* gpu, GrTexture* texture, GrSurfaceOrigin origin)
: INHERITED(texture, origin)
, fGpu(gpu) {
}
GrVkGpuTextureCommandBuffer(GrVkGpu* gpu) : fGpu(gpu) {}
~GrVkGpuTextureCommandBuffer() override;
@ -35,9 +32,14 @@ public:
void insertEventMarker(const char*) override;
private:
void submit() override;
void reset() {
fCopies.reset();
fTexture = nullptr;
}
void submit();
private:
struct CopyInfo {
CopyInfo(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
const SkIPoint& dstPoint)
@ -57,9 +59,7 @@ private:
class GrVkGpuRTCommandBuffer : public GrGpuRTCommandBuffer, private GrMesh::SendToGpuImpl {
public:
GrVkGpuRTCommandBuffer(GrVkGpu*, GrRenderTarget*, GrSurfaceOrigin,
const LoadAndStoreInfo&,
const StencilLoadAndStoreInfo&);
GrVkGpuRTCommandBuffer(GrVkGpu*);
~GrVkGpuRTCommandBuffer() override;
@ -74,7 +74,12 @@ public:
void copy(GrSurface* src, GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
const SkIPoint& dstPoint) override;
void submit() override;
void set(GrRenderTarget*, GrSurfaceOrigin,
const GrGpuRTCommandBuffer::LoadAndStoreInfo&,
const GrGpuRTCommandBuffer::StencilLoadAndStoreInfo&);
void reset();
void submit();
private:
void init();