[graphite] Partially connect Recorder, DrawBufferManager, DrawPass, and UniformCache.

Additionally, the default clip state was quick rejecting all the draws.

Bug: skia:12466
Change-Id: I8eaa95418bf24af2a5718c8cf21e97cdd7f80a34
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/465476
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
This commit is contained in:
Robert Phillips 2021-10-29 16:33:54 -04:00 committed by SkCQ
parent 6bb17ab48d
commit 60e456ecbb
9 changed files with 120 additions and 32 deletions

View File

@ -137,6 +137,11 @@ bool Device::onReadPixels(const SkPixmap& pm, int x, int y) {
return true;
}
SkIRect Device::onDevClipBounds() const {
auto target = fDC->target();
return SkIRect::MakeSize(target->dimensions());
}
void Device::drawPaint(const SkPaint& paint) {
SkRect deviceBounds = SkRect::Make(this->devClipBounds());
// TODO: Should be able to get the inverse from the matrix cache
@ -194,7 +199,7 @@ void Device::drawPoints(SkCanvas::PointMode mode, size_t count,
SkStrokeRec stroke(paint, SkPaint::kStroke_Style);
size_t inc = (mode == SkCanvas::kLines_PointMode) ? 2 : 1;
for (size_t i = 0; i < count; i += inc) {
this->drawShape(Shape(points[i], points[i + 1]), paint, stroke);
this->drawShape(Shape(points[i], points[(i + 1) % count]), paint, stroke);
}
}
}

View File

@ -41,8 +41,8 @@ protected:
bool onClipIsAA() const override { return false; }
bool onClipIsWideOpen() const override { return false; }
ClipType onGetClipType() const override { return ClipType::kEmpty; }
SkIRect onDevClipBounds() const override { return {}; }
ClipType onGetClipType() const override { return ClipType::kRect; }
SkIRect onDevClipBounds() const override;
void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {}
void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {}

View File

@ -43,8 +43,9 @@ DrawContext::DrawContext(sk_sp<TextureProxy> target, const SkImageInfo& ii)
DrawContext::~DrawContext() {
// If the SDC is destroyed and there are pending commands, they won't be drawn. Maybe that's ok
// but for now consider it a bug for not calling snapDrawTask() and snapRenderPassTask()
SkASSERT(fPendingDraws->drawCount() == 0);
SkASSERT(fDrawPasses.empty());
// TODO: determine why these asserts are firing on the GMs and re-enable
// SkASSERT(fPendingDraws->drawCount() == 0);
// SkASSERT(fDrawPasses.empty());
}
void DrawContext::stencilAndFillPath(const Transform& localToDevice,

View File

@ -9,12 +9,14 @@
#include "experimental/graphite/include/GraphiteTypes.h"
#include "experimental/graphite/src/ContextUtils.h"
#include "experimental/graphite/src/DrawBufferManager.h"
#include "experimental/graphite/src/DrawContext.h"
#include "experimental/graphite/src/DrawList.h"
#include "experimental/graphite/src/ProgramCache.h"
#include "experimental/graphite/src/Recorder.h"
#include "experimental/graphite/src/Renderer.h"
#include "experimental/graphite/src/TextureProxy.h"
#include "experimental/graphite/src/UniformCache.h"
#include "experimental/graphite/src/geom/BoundsManager.h"
#include "src/core/SkMathPriv.h"
@ -72,14 +74,16 @@ class DrawPass::SortKey {
public:
SortKey(const DrawList::Draw* draw,
int renderStep,
int pipelineIndex,
int geomUniformIndex,
int shadingUniformIndex)
uint32_t pipelineIndex,
uint32_t geomUniformIndex,
uint32_t shadingUniformIndex)
: fPipelineKey{draw->fOrder.paintOrder().bits(),
draw->fOrder.stencilIndex().bits(),
static_cast<uint32_t>(renderStep),
static_cast<uint32_t>(pipelineIndex)}
, fUniformKey{geomUniformIndex, shadingUniformIndex} {}
pipelineIndex}
, fUniformKey{geomUniformIndex, shadingUniformIndex}
, fDraw(draw) {
}
bool operator<(const SortKey& k) const {
uint64_t k1 = this->pipelineKey();
@ -88,11 +92,11 @@ public:
}
const DrawList::Draw* draw() const { return fDraw; }
int pipeline() const { return static_cast<int>(fPipelineKey.fPipeline); }
uint32_t pipeline() const { return fPipelineKey.fPipeline; }
int renderStep() const { return static_cast<int>(fPipelineKey.fRenderStep); }
int geometryUniforms() const { return static_cast<int>(fUniformKey.fGeometryIndex); }
int shadingUniforms() const { return static_cast<int>(fUniformKey.fShadingIndex); }
uint32_t geometryUniforms() const { return fUniformKey.fGeometryIndex; }
uint32_t shadingUniforms() const { return fUniformKey.fShadingIndex; }
private:
// Fields are ordered from most-significant to lowest when sorting by 128-bit value.
@ -106,8 +110,8 @@ private:
uint64_t pipelineKey() const { return sk_bit_cast<uint64_t>(fPipelineKey); }
struct {
int32_t fGeometryIndex; // bits >= log2(max steps * max draw count)
int32_t fShadingIndex; // ""
uint32_t fGeometryIndex; // bits >= log2(max steps * max draw count)
uint32_t fShadingIndex; // ""
} fUniformKey;
uint64_t uniformKey() const { return sk_bit_cast<uint64_t>(fUniformKey); }
@ -123,6 +127,16 @@ private:
///////////////////////////////////////////////////////////////////////////////////////////////////
namespace {
skgpu::UniformData* lookup(skgpu::Recorder* recorder, uint32_t uniformID) {
// TODO: just return a raw 'UniformData*' here
sk_sp<skgpu::UniformData> tmp = recorder->uniformCache()->lookup(uniformID);
return tmp.get();
}
} // anonymous namespace
DrawPass::DrawPass(sk_sp<TextureProxy> target, const SkIRect& bounds,
bool requiresStencil, bool requiresMSAA)
: fTarget(std::move(target))
@ -169,10 +183,10 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
// bound independently of those used by the rest of the RenderStep, then we can upload now
// and remember the location for re-use on any RenderStep that does shading.
uint32_t programID = ProgramCache::kInvalidProgramID;
uint32_t shadingID = UniformData::kInvalidUniformID;
uint32_t shadingUniformID = UniformData::kInvalidUniformID;
if (draw.fPaintParams.has_value()) {
std::tie(programID, shadingID) = get_ids_from_paint(recorder,
draw.fPaintParams.value());
std::tie(programID, shadingUniformID) = get_ids_from_paint(recorder,
draw.fPaintParams.value());
}
for (int stepIndex = 0; stepIndex < draw.fRenderer.numRenderSteps(); ++stepIndex) {
@ -180,19 +194,19 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
// TODO ask step to generate a pipeline description based on the above shading code, and
// have pipelineIndex point to that description in the accumulated list of descs
int pipelineIndex = 0;
uint32_t pipelineIndex = 0;
// TODO step writes out geometry uniforms and have geomIndex point to that buffer data,
// providing shape, transform, scissor, and paint depth to RenderStep
int geometryIndex = 0;
uint32_t geometryIndex = 0;
int shadingIndex = -1;
uint32_t shadingIndex = UniformData::kInvalidUniformID;
const bool performsShading = draw.fPaintParams.has_value() && step->performsShading();
if (performsShading) {
// TODO: we need to combine the 'programID' with the RenderPass info and the
// geometric rendering method to get the true 'pipelineIndex'
pipelineIndex = programID;
shadingIndex = shadingID;
shadingIndex = shadingUniformID;
} else {
// TODO: fill in 'pipelineIndex' for Chris' stencil/depth draws
}
@ -214,9 +228,11 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
// bugs in the DrawOrder determination code?
std::sort(keys.begin(), keys.end());
int lastPipeline = -1;
int lastShadingUniforms = -1;
int lastGeometryUniforms = -1;
DrawBufferManager* bufferMgr = recorder->drawBufferManager();
uint32_t lastPipeline = 0;
uint32_t lastShadingUniforms = UniformData::kInvalidUniformID;
uint32_t lastGeometryUniforms = 0;
SkIRect lastScissor = SkIRect::MakeSize(target->dimensions());
for (const SortKey& key : keys) {
const DrawList::Draw& draw = *key.draw();
@ -231,16 +247,20 @@ std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder,
if (key.pipeline() != lastPipeline) {
// TODO: Look up pipeline description from key's index and record binding it
lastPipeline = key.pipeline();
lastShadingUniforms = -1;
lastGeometryUniforms = -1;
lastShadingUniforms = UniformData::kInvalidUniformID;
lastGeometryUniforms = 0;
}
if (key.geometryUniforms() != lastGeometryUniforms) {
// TODO: Look up uniform buffer binding info corresponding to key's index and record it
lastGeometryUniforms = key.geometryUniforms();
}
if (key.shadingUniforms() != lastShadingUniforms) {
// TODO: As above, but for shading uniforms (assuming we have two descriptor
// sets for the different uniform sources).)
auto ud = lookup(recorder, key.shadingUniforms());
auto [writer, bufferInfo] = bufferMgr->getUniformWriter(ud->dataSize());
writer.write(ud->data(), ud->dataSize());
// TODO: recording 'bufferInfo' somewhere to allow a later uniform bind call
lastShadingUniforms = key.shadingUniforms();
}

View File

@ -9,6 +9,9 @@
#include "experimental/graphite/include/Context.h"
#include "experimental/graphite/src/CommandBuffer.h"
#include "experimental/graphite/src/ContextPriv.h"
#include "experimental/graphite/src/DrawBufferManager.h"
#include "experimental/graphite/src/Gpu.h"
#include "experimental/graphite/src/ProgramCache.h"
#include "experimental/graphite/src/Recording.h"
#include "experimental/graphite/src/UniformCache.h"
@ -18,7 +21,9 @@ namespace skgpu {
Recorder::Recorder(sk_sp<Context> context)
: fContext(std::move(context))
, fProgramCache(new ProgramCache)
, fUniformCache(new UniformCache) {
, fUniformCache(new UniformCache)
// TODO: Is '4' the correct initial alignment?
, fDrawBufferManager(new DrawBufferManager(fContext->priv().gpu()->resourceProvider(), 4)) {
}
Recorder::~Recorder() {}
@ -35,12 +40,17 @@ UniformCache* Recorder::uniformCache() {
return fUniformCache.get();
}
DrawBufferManager* Recorder::drawBufferManager() {
return fDrawBufferManager.get();
}
void Recorder::add(sk_sp<Task> task) {
fGraph.add(std::move(task));
}
std::unique_ptr<Recording> Recorder::snap() {
// TODO: need to create a CommandBuffer from the Tasks
// TODO: need to create a CommandBuffer from the Tasks and then we need to call
// fDrawBufferManager::transferBuffers() to pass the buffers to the command buffer.
fGraph.reset();
return std::unique_ptr<Recording>(new Recording(nullptr));
}

View File

@ -14,6 +14,7 @@
namespace skgpu {
class Context;
class DrawBufferManager;
class ProgramCache;
class Recording;
class UniformCache;
@ -28,6 +29,7 @@ public:
Context* context() const;
ProgramCache* programCache();
UniformCache* uniformCache();
DrawBufferManager* drawBufferManager();
std::unique_ptr<Recording> snap();
@ -37,6 +39,7 @@ private:
TaskGraph fGraph;
std::unique_ptr<ProgramCache> fProgramCache;
std::unique_ptr<UniformCache> fUniformCache;
std::unique_ptr<DrawBufferManager> fDrawBufferManager;
};
} // namespace skgpu

View File

@ -29,6 +29,8 @@ MTLPixelFormat SkColorTypeToFormat(SkColorType colorType) {
return MTLPixelFormatRGBA8Unorm;
case kAlpha_8_SkColorType:
return MTLPixelFormatR8Unorm;
case kRGBA_F16_SkColorType:
return MTLPixelFormatRGBA16Float;
default:
// TODO: fill in the rest of the formats
SkUNREACHABLE;
@ -86,4 +88,3 @@ sk_cfp<id<MTLLibrary>> CompileShaderLibrary(const Gpu* gpu,
}
} // namespace skgpu::mtl

47
gm/graphitestart.cpp Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright 2021 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm/gm.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
namespace skiagm {
// This is just for bootstrapping Graphite.
class GraphiteStartGM : public GM {
public:
GraphiteStartGM() {
this->setBGColor(0xFFCCCCCC);
}
protected:
SkString onShortName() override {
return SkString("graphitestart");
}
SkISize onISize() override {
return SkISize::Make(256, 256);
}
void onDraw(SkCanvas* canvas) override {
SkPaint p1, p2, p3;
p1.setColor(SK_ColorRED);
p2.setColor(SK_ColorGREEN);
p3.setColor(SK_ColorBLUE);
canvas->drawRect({10, 10, 100, 100}, p1);
canvas->drawRect({50, 50, 150, 150}, p2);
canvas->drawRect({100, 100, 200, 200}, p3);
}
};
//////////////////////////////////////////////////////////////////////////////
DEF_GM(return new GraphiteStartGM;)
} // namespace skiagm

View File

@ -198,6 +198,7 @@ gm_sources = [
"$_gm/gradients_degenerate.cpp",
"$_gm/gradients_no_texture.cpp",
"$_gm/gradtext.cpp",
"$_gm/graphitestart.cpp",
"$_gm/grayscalejpg.cpp",
"$_gm/hairlines.cpp",
"$_gm/hairmodes.cpp",