[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:
parent
40d7426345
commit
9af3a919ce
@ -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());
|
||||
|
@ -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.
|
||||
|
@ -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>();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user