From e47f0a0f1646ad31e0aeefd40a2cb1e1d275d18c Mon Sep 17 00:00:00 2001 From: Robert Phillips Date: Tue, 27 Mar 2018 17:01:16 -0400 Subject: Remove old method of drawing DDL SKPs from DM (in favor of ViaDDL method) Change-Id: I6bb270d9df1c76b9d2e384abde603cdda91c9bb6 Reviewed-on: https://skia-review.googlesource.com/116550 Commit-Queue: Mike Klein Reviewed-by: Mike Klein --- dm/DM.cpp | 6 +- dm/DMSrcSink.cpp | 325 ------------------------------------------------------- dm/DMSrcSink.h | 11 -- 3 files changed, 1 insertion(+), 341 deletions(-) (limited to 'dm') diff --git a/dm/DM.cpp b/dm/DM.cpp index 0c4b15f176..e134ac561c 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -788,11 +788,7 @@ static bool gather_srcs() { push_src("gm", "", new GMSrc(r->factory())); } - if (FLAGS_ddl > 0) { - gather_file_srcs(FLAGS_skps, "skp"); - } else { - gather_file_srcs(FLAGS_skps, "skp"); - } + gather_file_srcs(FLAGS_skps, "skp"); gather_file_srcs(FLAGS_mskps, "mskp"); #if !defined(SK_BUILD_FOR_GOOGLE3) gather_file_srcs(FLAGS_jsons, "json"); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 45977c0586..8dc24318d2 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -1203,331 +1203,6 @@ SkISize SKPSrc::size() const { Name SKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); } -/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ - -static const int kDDLViewportSize = 2048; -static const SkRect kDDLSKPViewport = { 0, 0, kDDLViewportSize, kDDLViewportSize }; - -DDLSKPSrc::DDLSKPSrc(Path path) : fPath(path) { } - -SkISize DDLSKPSrc::size() const { - SkRect viewport = get_cull_rect_for_skp(fPath.c_str()); - if (!viewport.intersect(kDDLSKPViewport)) { - return {0, 0}; - } - return viewport.roundOut().size(); -} - -Name DDLSKPSrc::name() const { return SkOSPath::Basename(fPath.c_str()); } - -#if !SK_SUPPORT_GPU - -Error DDLSKPSrc::draw(SkCanvas* canvas) const { - return SkStringPrintf("DDLs are GPU only\n"); -} - -#else - -class PromiseImageInfo { -public: - int fIndex; - sk_sp fImage; - SkBitmap fBitmap; - GrBackendTexture fBackendTexture; -}; - -static void promise_image_fulfill_proc(void* textureContext, GrBackendTexture* outTexture) { - const PromiseImageInfo* imgInfo = static_cast(textureContext); - - *outTexture = imgInfo->fBackendTexture; -} - -static void promise_image_release_proc(void* textureContext) { - // Do nothing. We free all the backend textures at the end. -} - -static void promise_image_done_proc(void* textureContext) { - // Do nothing. -} - -class PromiseImageCallbackContext { -public: - const SkTArray* fImageInfo; - SkDeferredDisplayListRecorder* fRecorder; -}; - -// This generates promise images to replace the indices in the compressed picture. This -// reconstitution is performed separately in each thread so we end of with multiple -// promise image referring to the same GrBackendTexture. -static sk_sp promise_image_creator(const void* rawData, size_t length, void* ctxIn) { - PromiseImageCallbackContext* ctx = static_cast(ctxIn); - const SkTArray* imageInfo = ctx->fImageInfo; - SkDeferredDisplayListRecorder* recorder = ctx->fRecorder; - - SkASSERT(length == sizeof(int)); - - const int* indexPtr = static_cast(rawData); - SkASSERT(*indexPtr < imageInfo->count()); - - const PromiseImageInfo& curImage = (*imageInfo)[*indexPtr]; - SkASSERT(curImage.fIndex == *indexPtr); - - GrBackendFormat backendFormat = curImage.fBackendTexture.format(); - - // DDL TODO: sort out mipmapping - sk_sp image = recorder->makePromiseTexture(backendFormat, - curImage.fBitmap.width(), - curImage.fBitmap.height(), - GrMipMapped::kNo, - GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin, - curImage.fBitmap.colorType(), - curImage.fBitmap.alphaType(), - curImage.fBitmap.refColorSpace(), - promise_image_fulfill_proc, - promise_image_release_proc, - promise_image_done_proc, - (void*) &curImage); - SkASSERT(image); - return image; -}; - -// DDL TODO: it would be great if we could draw the DDL directly into the destination SkSurface -Error DDLSKPSrc::draw(SkCanvas* canvas) const { - GrContext* context = canvas->getGrContext(); - if (!context) { - return SkStringPrintf("DDLs are GPU only\n"); - } - - if (1 == FLAGS_ddl) { - // If the number of x & y tiles is one just perform normal (non-DDL) rendering for - // comparison purposes - sk_sp picture = read_skp(fPath.c_str()); - if (!picture) { - return SkStringPrintf("Couldn't read %s.", fPath.c_str()); - } - - canvas->clipRect(kDDLSKPViewport); - canvas->drawPicture(std::move(picture)); - return ""; - } - - class TileData { - public: - // Note: we could just pass in surface characterization - TileData(sk_sp surf, const SkIRect& clip) - : fSurface(std::move(surf)) - , fClip(clip) { - SkAssertResult(fSurface->characterize(&fCharacterization)); - } - - // This method operates in parallel - // In each thread we will reconvert the compressedPictureData into an SkPicture - // replacing each image-index with a promise image. - void preprocess(SkData* compressedPictureData, - const SkTArray* imageInfo) { - SkDeferredDisplayListRecorder recorder(fCharacterization); - - // DDL TODO: the DDLRecorder's GrContext isn't initialized until getCanvas is called. - // Maybe set it up in the ctor? - SkCanvas* subCanvas = recorder.getCanvas(); - - sk_sp reconstitutedPicture; - - { - PromiseImageCallbackContext callbackCtx = { imageInfo, &recorder }; - - SkDeserialProcs procs; - procs.fImageCtx = &callbackCtx; - procs.fImageProc = promise_image_creator; - - reconstitutedPicture = SkPicture::MakeFromData(compressedPictureData, &procs); - if (!reconstitutedPicture) { - return; - } - } - - subCanvas->clipRect(SkRect::MakeWH(fClip.width(), fClip.height())); - subCanvas->translate(-fClip.fLeft, -fClip.fTop); - - // Note: in this use case we only render a picture to the deferred canvas - // but, more generally, clients will use arbitrary draw calls. - subCanvas->drawPicture(reconstitutedPicture); - - fDisplayList = recorder.detach(); - } - - // This method operates serially - void draw() { - fSurface->draw(fDisplayList.get()); - } - - // This method also operates serially - void compose(SkCanvas* dst) { - sk_sp img = fSurface->makeImageSnapshot(); - dst->save(); - dst->clipRect(SkRect::Make(fClip)); - dst->drawImage(std::move(img), fClip.fLeft, fClip.fTop); - dst->restore(); - } - - private: - sk_sp fSurface; - SkIRect fClip; // in the device space of the destination canvas - std::unique_ptr fDisplayList; - SkSurfaceCharacterization fCharacterization; - }; - - SkTArray tileData; - tileData.reserve(16); - - SkTArray imageInfo; - sk_sp compressedPictureData; - - SkIRect viewport; // this is our ultimate final drawing area/rect - - // DDL TODO: should we also be deduping in the following preprocessing? - - // Massage the input picture into something we can use with DDL - { - // In the first pass we read in an .skp file into an SkPicture recording all the images - // and getting a copy of their pixels in an uploadable form. - sk_sp firstPassPicture; - { - SkDeserialProcs procs; - - procs.fImageCtx = &imageInfo; - procs.fImageProc = [](const void* rawData, size_t length, void* ctx) -> sk_sp { - auto imageInfo = static_cast*>(ctx); - - sk_sp data = SkData::MakeWithCopy(rawData, length); - - PromiseImageInfo newImageInfo; - newImageInfo.fIndex = imageInfo->count(); - newImageInfo.fImage = SkImage::MakeFromEncoded(std::move(data)); - SkAssertResult(newImageInfo.fImage->asLegacyBitmap(&newImageInfo.fBitmap)); - - imageInfo->push_back(newImageInfo); - return newImageInfo.fImage; - }; - - firstPassPicture = read_skp(fPath.c_str(), &procs); - if (!firstPassPicture) { - return SkStringPrintf("Couldn't read %s.", fPath.c_str()); - } - - SkRect pictureCullRect = firstPassPicture->cullRect(); - SkAssertResult(pictureCullRect.intersect(kDDLSKPViewport)); - viewport = pictureCullRect.roundOut(); - } - - // In the second pass we convert the SkPicture into SkData replacing all the SkImages - // with an index into the imageInfo we collected in the first pass. - { - SkSerialProcs procs; - - procs.fImageCtx = &imageInfo; - procs.fImageProc = [](SkImage* image, void* ctx) -> sk_sp { - auto imageInfo = static_cast*>(ctx); - - int i; - for (i = 0; i < imageInfo->count(); ++i) { - if ((*imageInfo)[i].fImage.get() == image) { - break; - } - } - - SkASSERT(i < imageInfo->count()); - return SkData::MakeWithCopy(&i, sizeof(i)); - }; - - compressedPictureData = firstPassPicture->serialize(&procs); - if (!compressedPictureData) { - return SkStringPrintf("Couldn't re-serialize %s.", fPath.c_str()); - } - } - - // In the third pass we go through all the images and upload them to the GPU and - // get rid of the SkImage from the first pass - { - GrGpu* gpu = context->contextPriv().getGpu(); - if (!gpu) { - return SkStringPrintf("Couldn't get GPU from GrContext\n"); - } - - for (int i = 0; i < imageInfo.count(); ++i) { - // DDL TODO: how can we tell if we need mipmapping! - imageInfo[i].fBackendTexture = gpu->createTestingOnlyBackendTexture( - imageInfo[i].fBitmap.getPixels(), - imageInfo[i].fBitmap.width(), - imageInfo[i].fBitmap.height(), - imageInfo[i].fBitmap.colorType(), - false, GrMipMapped::kNo); - SkAssertResult(imageInfo[i].fBackendTexture.isValid()); - imageInfo[i].fImage = nullptr; // we don't need this anymore - } - } - } - - int xTileSize = viewport.width()/FLAGS_ddl; - int yTileSize = viewport.height()/FLAGS_ddl; - - // First, create the destination tiles - for (int y = 0, yOff = 0; y < FLAGS_ddl; ++y, yOff += yTileSize) { - int ySize = (y < FLAGS_ddl-1) ? yTileSize : viewport.height()-yOff; - - for (int x = 0, xOff = 0; x < FLAGS_ddl; ++x, xOff += xTileSize) { - int xSize = (x < FLAGS_ddl-1) ? xTileSize : viewport.width()-xOff; - - SkIRect clip = SkIRect::MakeXYWH(xOff, yOff, xSize, ySize); - - SkASSERT(viewport.contains(clip)); - - SkImageInfo tileII = SkImageInfo::MakeN32Premul(xSize, ySize); - - tileData.push_back(TileData(canvas->makeSurface(tileII), clip)); - } - } - - // Second, run the cpu pre-processing in threads - SkTaskGroup().batch(tileData.count(), [&](int i) { - tileData[i].preprocess(compressedPictureData.get(), &imageInfo); - }); - - // Third, synchronously render the display lists into the dest tiles - // TODO: it would be cool to not wait until all the tiles are drawn to begin - // drawing to the GPU - for (int i = 0; i < tileData.count(); ++i) { - tileData[i].draw(); - } - - // Finally, compose the drawn tiles into the result - // Note: the separation between the tiles and the final composition better - // matches Chrome but costs us a copy - for (int i = 0; i < tileData.count(); ++i) { - tileData[i].compose(canvas); - } - - // All promise images need to be fulfulled before leaving this method since we are about to - // delete their backing GrBackendTextures - context->flush(); - - // Clean up VRAM - { - GrGpu* gpu = context->contextPriv().getGpu(); - if (!gpu) { - return SkStringPrintf("Couldn't get GPU from GrContext\n"); - } - - for (int i = 0; i < imageInfo.count(); ++i) { - gpu->deleteTestingOnlyBackendTexture(imageInfo[i].fBackendTexture); - } - } - - return ""; -} - -#endif - /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #if !defined(SK_BUILD_FOR_GOOGLE3) diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 65c9b7350a..5ba11e57be 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -251,17 +251,6 @@ private: Path fPath; }; -// DeferredDisplayList flavor -class DDLSKPSrc : public Src { -public: - explicit DDLSKPSrc(Path path); - - Error draw(SkCanvas*) const override; - SkISize size() const override; - Name name() const override; -private: - Path fPath; -}; #if !defined(SK_BUILD_FOR_GOOGLE3) class SkottieSrc final : public Src { -- cgit v1.2.3