[graphite] Hook up Surface::writePixels

Bug: skia:12845
Change-Id: I8013b0068ab758e9a5e580344c62e4680f4fa48e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/506176
Commit-Queue: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
Jim Van Verth 2022-02-11 09:46:00 -05:00 committed by SkCQ
parent 40d7426345
commit 9af3a919ce
7 changed files with 85 additions and 5 deletions

View File

@ -246,6 +246,12 @@ bool Device::readPixels(Context* context,
return true;
}
bool Device::onWritePixels(const SkPixmap& pm, int x, int y) {
this->flushPendingWorkToRecorder();
return fDC->writePixels(fRecorder, pm, {x, y});
}
SkIRect Device::onDevClipBounds() const {
auto target = fDC->target();
return SkIRect::MakeSize(target->dimensions());
@ -469,6 +475,11 @@ void Device::flushPendingWorkToRecorder() {
// TODO: we may need to further split this function up since device->device drawList and
// DrawPass stealing will need to share some of the same logic w/o becoming a Task.
auto uploadTask = fDC->snapUploadTask(fRecorder);
if (uploadTask) {
fRecorder->priv().add(std::move(uploadTask));
}
// TODO: iterate the clip stack and issue a depth-only draw for every clip element that has
// a non-empty usage bounds, using that bounds as the scissor.
auto drawTask = fDC->snapRenderPassTask(fRecorder, fColorDepthBoundsManager.get());

View File

@ -93,7 +93,7 @@ private:
void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {}
void onReplaceClip(const SkIRect& rect) override {}
bool onWritePixels(const SkPixmap&, int x, int y) override { return false; }
bool onWritePixels(const SkPixmap&, int x, int y) override;
// TODO: This will likely be implemented with the same primitive building block that drawRect
// and drawRRect will rely on.

View File

@ -7,6 +7,7 @@
#include "experimental/graphite/src/DrawContext.h"
#include "include/core/SkPixmap.h"
#include "include/private/SkColorData.h"
#include "experimental/graphite/include/Context.h"
@ -47,7 +48,8 @@ sk_sp<DrawContext> DrawContext::Make(sk_sp<TextureProxy> target,
DrawContext::DrawContext(sk_sp<TextureProxy> target, const SkImageInfo& ii)
: fTarget(std::move(target))
, fImageInfo(ii)
, fPendingDraws(std::make_unique<DrawList>()) {
, fPendingDraws(std::make_unique<DrawList>())
, fPendingUploads(std::make_unique<UploadList>()) {
// TBD - Will probably want DrawLists (and its internal commands) to come from an arena
// that the DC manages.
}
@ -97,6 +99,52 @@ void DrawContext::clear(const SkColor4f& clearColor) {
fDrawPasses.clear();
}
//
// TODO: The other draw-recording APIs in DrawContext are relatively simple, just storing state
// from the caller's decision making. If possible we should consider moving the more complex logic
// somewhere above DrawContext and have this be much simpler.
bool DrawContext::writePixels(Recorder* recorder, const SkPixmap& src, SkIPoint dstPoint) {
// TODO: add mipmap support for createBackendTexture
// Our caller should have clipped to the bounds of the surface already.
SkASSERT(SkIRect::MakeSize(fTarget->dimensions()).contains(
SkIRect::MakePtSize(dstPoint, src.dimensions())));
if (!recorder) {
return false;
}
if (src.colorType() == kUnknown_SkColorType) {
return false;
}
// TODO: check for readOnly or framebufferOnly target and return false if so
const Caps* caps = recorder->priv().caps();
// TODO: canvas2DFastPath?
// TODO: check that surface supports writePixels
// TODO: handle writePixels as draw if needed (e.g., canvas2DFastPath || !supportsWritePixels)
// TODO: check for flips and conversions and either handle here or pass info to appendUpload
// for now, until conversions are supported
if (!caps->areColorTypeAndTextureInfoCompatible(src.colorType(),
fTarget->textureInfo())) {
return false;
}
std::vector<MipLevel> levels;
levels.push_back({src.addr(), src.rowBytes()});
SkIRect dstRect = SkIRect::MakePtSize(dstPoint, src.dimensions());
return fPendingUploads->appendUpload(recorder,
fTarget,
src.colorType(),
levels,
dstRect);
}
void DrawContext::snapDrawPass(Recorder* recorder, const BoundsManager* occlusionCuller) {
if (fPendingDraws->drawCount() == 0) {
return;
@ -147,6 +195,10 @@ sk_sp<Task> DrawContext::snapRenderPassTask(Recorder* recorder,
}
sk_sp<Task> DrawContext::snapUploadTask(Recorder* recorder) {
if (!fPendingUploads) {
return nullptr;
}
sk_sp<Task> uploadTask = UploadTask::Make(fPendingUploads.get());
fPendingUploads = std::make_unique<UploadList>();

View File

@ -18,6 +18,8 @@
#include <vector>
class SkPixmap;
namespace skgpu {
class BoundsManager;
@ -71,6 +73,10 @@ public:
DrawOrder order,
const PaintParams* paint);
bool writePixels(Recorder* recorder,
const SkPixmap& src,
SkIPoint dstPt);
// Ends the current DrawList being accumulated by the SDC, converting it into an optimized and
// immutable DrawPass. The DrawPass will be ordered after any other snapped DrawPasses or
// appended DrawPasses from a child SDC. A new DrawList is started to record subsequent drawing

View File

@ -34,7 +34,10 @@ sk_sp<SkImage> Surface::onNewImageSnapshot(const SkIRect* subset) {
return sk_sp<Image_Graphite>(new Image_Graphite(ii));
}
void Surface::onWritePixels(const SkPixmap&, int x, int y) {}
void Surface::onWritePixels(const SkPixmap& pixmap, int x, int y) {
fDevice->writePixels(pixmap, x, y);
}
bool Surface::onCopyOnWrite(ContentChangeMode) { return true; }
bool Surface::onReadPixels(Context* context,

View File

@ -139,7 +139,7 @@ bool UploadList::appendUpload(Recorder* recorder,
copyData[currentMipLevel].fBufferRowBytes = trimRowBytes;
copyData[currentMipLevel].fRect = {
dstRect.left(), dstRect.top(), // TODO: can we recompute this for mips?
currentWidth, currentHeight
dstRect.left() + currentWidth, dstRect.top() + currentHeight
};
copyData[currentMipLevel].fMipLevel = currentMipLevel;

View File

@ -10,6 +10,7 @@
#include "include/core/SkImage.h"
#include "include/core/SkPaint.h"
#include "include/effects/SkGradientShader.h"
#include "tools/Resources.h"
namespace {
@ -61,6 +62,7 @@ class GraphiteStartGM : public GM {
public:
GraphiteStartGM() {
this->setBGColor(0xFFCCCCCC);
GetResourceAsBitmap("images/color_wheel.gif", &fBitmap);
}
protected:
@ -69,7 +71,7 @@ protected:
}
SkISize onISize() override {
return SkISize::Make(256, 256);
return SkISize::Make(256, 384);
}
void onDraw(SkCanvas* canvas) override {
@ -102,7 +104,13 @@ protected:
p.setShader(create_blend_shader(SkBlendMode::kDstOver));
canvas->drawRect({129, 129, 255, 255}, p);
}
#ifdef SK_GRAPHITE_ENABLED
// TODO: failing serialize test on Linux, not sure what's going on
canvas->writePixels(fBitmap, 0, 256);
#endif
}
SkBitmap fBitmap;
};
//////////////////////////////////////////////////////////////////////////////