Update DDL testing harness to support drawing DDL w/ integer offsets
This isn't hooked up anywhere but breaks up the omnibus CL. Change-Id: I15c200e57450e7cc8ee95a3f7969926d0eb8487f Reviewed-on: https://skia-review.googlesource.com/c/skia/+/333129 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
e96c19e902
commit
0c0884991d
@ -1814,7 +1814,8 @@ Result GPUDDLSink::ddlDraw(const Src& src,
|
||||
// one. About all it can be consistently used for is GrCaps access and 'defaultBackendFormat'
|
||||
// calls.
|
||||
constexpr int kNumDivisions = 3;
|
||||
DDLTileHelper tiles(gpuThreadCtx, dstCharacterization, viewport, kNumDivisions);
|
||||
DDLTileHelper tiles(gpuThreadCtx, dstCharacterization, viewport, kNumDivisions,
|
||||
/* addRandomPaddingToDst */ false);
|
||||
|
||||
tiles.createBackendTextures(gpuTaskGroup, gpuThreadCtx);
|
||||
|
||||
@ -2268,7 +2269,8 @@ Result ViaDDL::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkStrin
|
||||
canvas->clear(SK_ColorTRANSPARENT);
|
||||
}
|
||||
// First, create all the tiles (including their individual dest surfaces)
|
||||
DDLTileHelper tiles(direct, dstCharacterization, viewport, fNumDivisions);
|
||||
DDLTileHelper tiles(direct, dstCharacterization, viewport, fNumDivisions,
|
||||
/* addRandomPaddingToDst */ false);
|
||||
|
||||
tiles.createBackendTextures(nullptr, direct);
|
||||
|
||||
|
@ -1007,18 +1007,25 @@ public:
|
||||
*/
|
||||
bool characterize(SkSurfaceCharacterization* characterization) const;
|
||||
|
||||
/** Draws deferred display list created using SkDeferredDisplayListRecorder.
|
||||
Has no effect and returns false if SkSurfaceCharacterization stored in
|
||||
deferredDisplayList is not compatible with SkSurface.
|
||||
/** Draws the deferred display list created via a SkDeferredDisplayListRecorder.
|
||||
If the deferred display list is not compatible with this SkSurface, the draw is skipped
|
||||
and false is return.
|
||||
|
||||
raster surface returns false.
|
||||
The xOffset and yOffset parameters are experimental and, if not both zero, will cause
|
||||
the draw to be ignored.
|
||||
When implemented, if xOffset or yOffset are non-zero, the DDL will be drawn offset by that
|
||||
amount into the surface.
|
||||
|
||||
@param deferredDisplayList drawing commands
|
||||
@param xOffset x-offset at which to draw the DDL
|
||||
@param yOffset y-offset at which to draw the DDL
|
||||
@return false if deferredDisplayList is not compatible
|
||||
|
||||
example: https://fiddle.skia.org/c/@Surface_draw_2
|
||||
*/
|
||||
bool draw(sk_sp<const SkDeferredDisplayList> deferredDisplayList);
|
||||
bool draw(sk_sp<const SkDeferredDisplayList> deferredDisplayList,
|
||||
int xOffset = 0,
|
||||
int yOffset = 0);
|
||||
|
||||
protected:
|
||||
SkSurface(int width, int height, const SkSurfaceProps* surfaceProps);
|
||||
|
@ -338,8 +338,12 @@ bool SkSurface::isCompatible(const SkSurfaceCharacterization& characterization)
|
||||
return asConstSB(this)->onIsCompatible(characterization);
|
||||
}
|
||||
|
||||
bool SkSurface::draw(sk_sp<const SkDeferredDisplayList> ddl) {
|
||||
return asSB(this)->onDraw(std::move(ddl));
|
||||
bool SkSurface::draw(sk_sp<const SkDeferredDisplayList> ddl, int xOffset, int yOffset) {
|
||||
if (xOffset != 0 || yOffset != 0) {
|
||||
return false; // the offsets currently aren't supported
|
||||
}
|
||||
|
||||
return asSB(this)->onDraw(std::move(ddl), xOffset, yOffset);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -125,7 +125,9 @@ public:
|
||||
|
||||
virtual bool onCharacterize(SkSurfaceCharacterization*) const { return false; }
|
||||
virtual bool onIsCompatible(const SkSurfaceCharacterization&) const { return false; }
|
||||
virtual bool onDraw(sk_sp<const SkDeferredDisplayList>) { return false; }
|
||||
virtual bool onDraw(sk_sp<const SkDeferredDisplayList>, int xOffset, int yOffset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline SkCanvas* getCachedCanvas();
|
||||
inline sk_sp<SkImage> refCachedImage();
|
||||
|
@ -355,7 +355,7 @@ bool SkSurface_Gpu::onIsCompatible(const SkSurfaceCharacterization& characteriza
|
||||
characterization.surfaceProps() == rtc->surfaceProps();
|
||||
}
|
||||
|
||||
bool SkSurface_Gpu::onDraw(sk_sp<const SkDeferredDisplayList> ddl) {
|
||||
bool SkSurface_Gpu::onDraw(sk_sp<const SkDeferredDisplayList> ddl, int xOffset, int yOffset) {
|
||||
if (!ddl || !this->isCompatible(ddl->characterization())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
bool onCharacterize(SkSurfaceCharacterization*) const override;
|
||||
bool onIsCompatible(const SkSurfaceCharacterization&) const override;
|
||||
void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) override;
|
||||
bool onDraw(sk_sp<const SkDeferredDisplayList>) override;
|
||||
bool onDraw(sk_sp<const SkDeferredDisplayList>, int xOffset, int yOffset) override;
|
||||
|
||||
SkGpuDevice* getDevice() { return fDevice.get(); }
|
||||
|
||||
|
@ -22,11 +22,14 @@
|
||||
void DDLTileHelper::TileData::init(int id,
|
||||
GrDirectContext* direct,
|
||||
const SkSurfaceCharacterization& dstSurfaceCharacterization,
|
||||
const SkIRect& clip) {
|
||||
const SkIRect& clip,
|
||||
const SkIRect& paddingOutsets) {
|
||||
fID = id;
|
||||
fClip = clip;
|
||||
fPaddingOutsets = paddingOutsets;
|
||||
|
||||
fCharacterization = dstSurfaceCharacterization.createResized(clip.width(), clip.height());
|
||||
fCharacterization = dstSurfaceCharacterization.createResized(this->paddedRectSize().width(),
|
||||
this->paddedRectSize().height());
|
||||
SkASSERT(fCharacterization.isValid());
|
||||
|
||||
GrBackendFormat backendFormat = direct->defaultBackendFormat(fCharacterization.colorType(),
|
||||
@ -78,6 +81,7 @@ void DDLTileHelper::TileData::createDDL() {
|
||||
}
|
||||
}
|
||||
|
||||
// We always record the DDL in the (0,0) .. (clipWidth, clipHeight) coordinates
|
||||
recordingCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height()));
|
||||
recordingCanvas->translate(-fClip.fLeft, -fClip.fTop);
|
||||
|
||||
@ -98,14 +102,15 @@ void DDLTileHelper::createComposeDDL() {
|
||||
for (int i = 0; i < this->numTiles(); ++i) {
|
||||
TileData* tile = &fTiles[i];
|
||||
|
||||
sk_sp<SkImage> promiseImage = tile->makePromiseImage(&recorder);
|
||||
sk_sp<SkImage> promiseImage = tile->makePromiseImageForDst(&recorder);
|
||||
|
||||
SkIRect clipRect = tile->clipRect();
|
||||
SkRect dstRect = SkRect::Make(tile->clipRect());
|
||||
SkIRect srcRect = tile->clipRect();
|
||||
srcRect.offsetTo(tile->padOffset().x(), tile->padOffset().y());
|
||||
|
||||
SkASSERT(clipRect.width() == promiseImage->width() &&
|
||||
clipRect.height() == promiseImage->height());
|
||||
SkASSERT(promiseImage->bounds().contains(srcRect));
|
||||
|
||||
recordingCanvas->drawImage(promiseImage, clipRect.fLeft, clipRect.fTop);
|
||||
recordingCanvas->drawImageRect(promiseImage.get(), srcRect, dstRect, nullptr);
|
||||
}
|
||||
|
||||
fComposeDDL = recorder.detach();
|
||||
@ -148,6 +153,7 @@ void DDLTileHelper::TileData::drawSKPDirectly(GrRecordingContext* context) {
|
||||
if (fTileSurface) {
|
||||
SkCanvas* tileCanvas = fTileSurface->getCanvas();
|
||||
|
||||
SkASSERT(this->padOffset().isZero() && this->paddedRectSize() == fClip.size());
|
||||
tileCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height()));
|
||||
tileCanvas->translate(-fClip.fLeft, -fClip.fTop);
|
||||
|
||||
@ -167,7 +173,7 @@ void DDLTileHelper::TileData::draw(GrDirectContext* direct) {
|
||||
// (maybe in GrDrawingManager::addDDLTarget).
|
||||
fTileSurface = this->makeWrappedTileDest(direct);
|
||||
if (fTileSurface) {
|
||||
fTileSurface->draw(fDisplayList);
|
||||
fTileSurface->draw(fDisplayList, this->padOffset().x(), this->padOffset().y());
|
||||
|
||||
// We can't snap an image here bc, since we're using wrapped backend textures for the
|
||||
// surfaces, that would incur a copy.
|
||||
@ -181,14 +187,15 @@ void DDLTileHelper::TileData::reset() {
|
||||
fTileSurface = nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImage(SkDeferredDisplayListRecorder* recorder) {
|
||||
sk_sp<SkImage> DDLTileHelper::TileData::makePromiseImageForDst(
|
||||
SkDeferredDisplayListRecorder* recorder) {
|
||||
SkASSERT(fCallbackContext);
|
||||
|
||||
// The promise image gets a ref on the promise callback context
|
||||
sk_sp<SkImage> promiseImage =
|
||||
recorder->makePromiseTexture(fCallbackContext->backendFormat(),
|
||||
fClip.width(),
|
||||
fClip.height(),
|
||||
this->paddedRectSize().width(),
|
||||
this->paddedRectSize().height(),
|
||||
GrMipmapped::kNo,
|
||||
GrSurfaceOrigin::kBottomLeft_GrSurfaceOrigin,
|
||||
fCharacterization.colorType(),
|
||||
@ -230,7 +237,8 @@ void DDLTileHelper::TileData::DeleteBackendTexture(GrDirectContext*, TileData* t
|
||||
DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
|
||||
const SkSurfaceCharacterization& dstChar,
|
||||
const SkIRect& viewport,
|
||||
int numDivisions)
|
||||
int numDivisions,
|
||||
bool addRandomPaddingToDst)
|
||||
: fNumDivisions(numDivisions)
|
||||
, fTiles(numDivisions * numDivisions)
|
||||
, fDstCharacterization(dstChar) {
|
||||
@ -239,6 +247,8 @@ DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
|
||||
int xTileSize = viewport.width()/fNumDivisions;
|
||||
int yTileSize = viewport.height()/fNumDivisions;
|
||||
|
||||
SkRandom rand;
|
||||
|
||||
// Create the destination tiles
|
||||
for (int y = 0, yOff = 0; y < fNumDivisions; ++y, yOff += yTileSize) {
|
||||
int ySize = (y < fNumDivisions-1) ? yTileSize : viewport.height()-yOff;
|
||||
@ -250,7 +260,14 @@ DDLTileHelper::DDLTileHelper(GrDirectContext* direct,
|
||||
|
||||
SkASSERT(viewport.contains(clip));
|
||||
|
||||
fTiles[y*fNumDivisions+x].init(y*fNumDivisions+x, direct, dstChar, clip);
|
||||
static const uint32_t kMaxPad = 64;
|
||||
int32_t lPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
|
||||
int32_t tPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
|
||||
int32_t rPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
|
||||
int32_t bPad = addRandomPaddingToDst ? rand.nextRangeU(0, kMaxPad) : 0;
|
||||
|
||||
fTiles[y*fNumDivisions+x].init(y*fNumDivisions+x, direct, dstChar, clip,
|
||||
{lPad, tPad, rPad, bPad});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ public:
|
||||
void init(int id,
|
||||
GrDirectContext*,
|
||||
const SkSurfaceCharacterization& dstChar,
|
||||
const SkIRect& clip);
|
||||
const SkIRect& clip,
|
||||
const SkIRect& paddingOutsets);
|
||||
|
||||
// Convert the compressedPictureData into an SkPicture replacing each image-index
|
||||
// with a promise image.
|
||||
@ -62,10 +63,15 @@ public:
|
||||
|
||||
int id() const { return fID; }
|
||||
SkIRect clipRect() const { return fClip; }
|
||||
SkISize paddedRectSize() const {
|
||||
return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
|
||||
fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
|
||||
}
|
||||
SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
|
||||
|
||||
SkDeferredDisplayList* ddl() { return fDisplayList.get(); }
|
||||
|
||||
sk_sp<SkImage> makePromiseImage(SkDeferredDisplayListRecorder*);
|
||||
sk_sp<SkImage> makePromiseImageForDst(SkDeferredDisplayListRecorder*);
|
||||
void dropCallbackContext() { fCallbackContext.reset(); }
|
||||
|
||||
static void CreateBackendTexture(GrDirectContext*, TileData*);
|
||||
@ -78,6 +84,7 @@ public:
|
||||
|
||||
int fID = -1;
|
||||
SkIRect fClip; // in the device space of the final SkSurface
|
||||
SkIRect fPaddingOutsets; // random padding for the output surface
|
||||
SkSurfaceCharacterization fCharacterization; // characterization for the tile's surface
|
||||
|
||||
// The callback context holds (via its SkPromiseImageTexture) the backend texture
|
||||
@ -99,7 +106,8 @@ public:
|
||||
DDLTileHelper(GrDirectContext*,
|
||||
const SkSurfaceCharacterization& dstChar,
|
||||
const SkIRect& viewport,
|
||||
int numDivisions);
|
||||
int numDivisions,
|
||||
bool addRandomPaddingToDst);
|
||||
|
||||
void createSKPPerTile(SkData* compressedPictureData, const DDLPromiseImageHelper&);
|
||||
|
||||
|
@ -269,7 +269,8 @@ static void run_ddl_benchmark(sk_gpu_test::TestContext* testContext, GrDirectCon
|
||||
|
||||
promiseImageHelper.uploadAllToGPU(nullptr, context);
|
||||
|
||||
DDLTileHelper tiles(context, dstCharacterization, viewport, FLAGS_ddlTilingWidthHeight);
|
||||
DDLTileHelper tiles(context, dstCharacterization, viewport, FLAGS_ddlTilingWidthHeight,
|
||||
/* addRandomPaddingToDst */ false);
|
||||
|
||||
tiles.createBackendTextures(nullptr, context);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user