| #Topic Surface | |
| #Alias Surface_Reference ## | |
| #Class SkSurface | |
| #Code | |
| #Populate | |
| ## | |
| SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be | |
| allocated either in CPU memory, if a raster surface; or on the GPU, for a GrRenderTarget surface. | |
| SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call | |
| surface->getCanvas() to use that canvas. The caller should not delete the returned canvas; | |
| it is owned by surface. | |
| SkSurface always has non-zero dimensions. If there is a request for a new surface, and either | |
| of the requested dimensions are zero, then nullptr will be returned. | |
| # ------------------------------------------------------------------------------ | |
| #Typedef void* ReleaseContext | |
| #Line # context for release procs ## | |
| ## | |
| #Typedef void (*RenderTargetReleaseProc)(ReleaseContext releaseContext) | |
| #Line # context for release procs ## | |
| ## | |
| #Typedef void (*TextureReleaseProc)(ReleaseContext releaseContext) | |
| #Line # context for release procs ## | |
| ## | |
| #Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels, | |
| size_t rowBytes, | |
| const SkSurfaceProps* surfaceProps = nullptr) | |
| #In Constructors | |
| #Line # creates Surface from SkImageInfo and Pixel_Storage ## | |
| #Populate | |
| #Example | |
| void draw(SkCanvas* ) { | |
| SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); | |
| const size_t size = info.computeMinByteSize(); | |
| SkAutoTMalloc<SkPMColor> storage(size); | |
| SkPMColor* pixels = storage.get(); | |
| sk_sp<SkSurface> surface(SkSurface::MakeRasterDirect(info, pixels, info.minRowBytes())); | |
| SkCanvas* canvas = surface->getCanvas(); | |
| canvas->clear(SK_ColorWHITE); | |
| SkPMColor pmWhite = pixels[0]; | |
| SkPaint paint; | |
| canvas->drawPoint(1, 1, paint); | |
| canvas->flush(); // ensure that point was drawn | |
| for (int y = 0; y < info.height(); ++y) { | |
| for (int x = 0; x < info.width(); ++x) { | |
| SkDebugf("%c", *pixels++ == pmWhite ? '-' : 'x'); | |
| } | |
| SkDebugf("\n"); | |
| } | |
| } | |
| #StdOut | |
| --- | |
| -x- | |
| --- | |
| ## | |
| ## | |
| #SeeAlso MakeRasterDirectReleaseProc MakeRaster MakeRasterN32Premul SkCanvas::MakeRasterDirect | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRasterDirectReleaseProc(const SkImageInfo& imageInfo, void* pixels, | |
| size_t rowBytes, | |
| void (*releaseProc)(void* pixels, void* context), | |
| void* context, const SkSurfaceProps* surfaceProps = nullptr) | |
| #In Constructors | |
| #Line # creates Surface from SkImageInfo and Pixel_Storage ## | |
| #Populate | |
| #Example | |
| #Function | |
| static void release_direct_surface_storage(void* pixels, void* context) { | |
| if (pixels == context) { | |
| SkDebugf("expected release context\n"); | |
| } | |
| sk_free(pixels); | |
| } | |
| ## | |
| void draw(SkCanvas* ) { | |
| SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); | |
| const size_t rowBytes = info.minRowBytes(); | |
| void* pixels = sk_malloc_throw(info.computeByteSize(rowBytes)); | |
| sk_sp<SkSurface> surface(SkSurface::MakeRasterDirectReleaseProc(info, pixels, rowBytes, | |
| release_direct_surface_storage, pixels)); | |
| SkCanvas* canvas = surface->getCanvas(); | |
| canvas->clear(SK_ColorWHITE); | |
| SkPMColor* colorPtr = (SkPMColor*) pixels; | |
| SkPMColor pmWhite = colorPtr[0]; | |
| SkPaint paint; | |
| canvas->drawPoint(1, 1, paint); | |
| canvas->flush(); // ensure that point was drawn | |
| for (int y = 0; y < info.height(); ++y) { | |
| for (int x = 0; x < info.width(); ++x) { | |
| SkDebugf("%c", *colorPtr++ == pmWhite ? '-' : 'x'); | |
| } | |
| SkDebugf("\n"); | |
| } | |
| } | |
| #StdOut | |
| --- | |
| -x- | |
| --- | |
| expected release context | |
| ## | |
| ## | |
| #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRaster | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, size_t rowBytes, | |
| const SkSurfaceProps* surfaceProps) | |
| #In Constructors | |
| #Line # creates Surface from SkImageInfo ## | |
| #Populate | |
| #Example | |
| void draw(SkCanvas* ) { | |
| SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); | |
| const size_t rowBytes = 64; | |
| sk_sp<SkSurface> surface(SkSurface::MakeRaster(info, rowBytes, nullptr)); | |
| SkCanvas* canvas = surface->getCanvas(); | |
| canvas->clear(SK_ColorWHITE); | |
| SkPixmap pixmap; | |
| if (surface->peekPixels(&pixmap)) { | |
| const uint32_t* colorPtr = pixmap.addr32(); | |
| SkPMColor pmWhite = colorPtr[0]; | |
| SkPaint paint; | |
| canvas->drawPoint(1, 1, paint); | |
| canvas->flush(); // ensure that point was drawn | |
| for (int y = 0; y < info.height(); ++y) { | |
| for (int x = 0; x < info.width(); ++x) { | |
| SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); | |
| } | |
| colorPtr += rowBytes / sizeof(colorPtr[0]); | |
| SkDebugf("\n"); | |
| } | |
| } | |
| } | |
| #StdOut | |
| --- | |
| -x- | |
| --- | |
| ## | |
| ## | |
| #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRaster(const SkImageInfo& imageInfo, | |
| const SkSurfaceProps* props = nullptr) | |
| #Populate | |
| #Example | |
| void draw(SkCanvas* ) { | |
| SkImageInfo info = SkImageInfo::MakeN32Premul(3, 3); | |
| sk_sp<SkSurface> surface(SkSurface::MakeRaster(info)); | |
| SkCanvas* canvas = surface->getCanvas(); | |
| canvas->clear(SK_ColorWHITE); | |
| SkPixmap pixmap; | |
| if (surface->peekPixels(&pixmap)) { | |
| const uint32_t* colorPtr = pixmap.addr32(); | |
| SkPMColor pmWhite = colorPtr[0]; | |
| SkPaint paint; | |
| canvas->drawPoint(1, 1, paint); | |
| canvas->flush(); // ensure that point was drawn | |
| for (int y = 0; y < info.height(); ++y) { | |
| for (int x = 0; x < info.width(); ++x) { | |
| SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); | |
| } | |
| colorPtr += info.width(); | |
| SkDebugf("\n"); | |
| } | |
| } | |
| } | |
| ## | |
| #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRasterN32Premul(int width, int height, | |
| const SkSurfaceProps* surfaceProps = nullptr) | |
| #In Constructors | |
| #Line # creates Surface from width, height matching output ## | |
| #Populate | |
| #Example | |
| void draw(SkCanvas* ) { | |
| sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(3, 3)); | |
| SkCanvas* canvas = surface->getCanvas(); | |
| canvas->clear(SK_ColorWHITE); | |
| SkPixmap pixmap; | |
| if (surface->peekPixels(&pixmap)) { | |
| const uint32_t* colorPtr = pixmap.addr32(); | |
| SkPMColor pmWhite = colorPtr[0]; | |
| SkPaint paint; | |
| canvas->drawPoint(1, 1, paint); | |
| canvas->flush(); // ensure that point was drawn | |
| for (int y = 0; y < surface->height(); ++y) { | |
| for (int x = 0; x < surface->width(); ++x) { | |
| SkDebugf("%c", colorPtr[x] == pmWhite ? '-' : 'x'); | |
| } | |
| colorPtr += surface->width(); | |
| SkDebugf("\n"); | |
| } | |
| } | |
| } | |
| #StdOut | |
| --- | |
| -x- | |
| --- | |
| ## | |
| ## | |
| #SeeAlso MakeRasterDirect MakeRasterN32Premul MakeRasterDirectReleaseProc | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeFromBackendTexture(GrContext* context, | |
| const GrBackendTexture& backendTexture, | |
| GrSurfaceOrigin origin, int sampleCnt, | |
| SkColorType colorType, | |
| sk_sp<SkColorSpace> colorSpace, | |
| const SkSurfaceProps* surfaceProps, | |
| TextureReleaseProc textureReleaseProc = nullptr, | |
| ReleaseContext releaseContext = nullptr) | |
| #In Constructors | |
| #Line # creates Surface from GPU texture ## | |
| #Populate | |
| #Example | |
| #Platform gpu cpu | |
| #Image 3 | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTexture(context, | |
| backEndTexture, kTopLeft_GrSurfaceOrigin, 0, | |
| kRGBA_8888_SkColorType, nullptr, nullptr); | |
| auto surfaceCanvas = gpuSurface->getCanvas(); | |
| surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context, | |
| const GrBackendRenderTarget& backendRenderTarget, | |
| GrSurfaceOrigin origin, | |
| SkColorType colorType, | |
| sk_sp<SkColorSpace> colorSpace, | |
| const SkSurfaceProps* surfaceProps, | |
| RenderTargetReleaseProc releaseProc = nullptr, | |
| ReleaseContext releaseContext = nullptr) | |
| #In Constructors | |
| #Line # creates Surface from GPU render target ## | |
| #Populate | |
| #Example | |
| #ToDo remove !fiddle below once backEndTextureRenderTarget is available ## | |
| #Platform !fiddle gpu | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendRenderTarget(context, | |
| backEndRenderTarget, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, | |
| nullptr, nullptr); | |
| auto surfaceCanvas = gpuSurface->getCanvas(); | |
| surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso MakeFromBackendTexture MakeRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context, | |
| const GrBackendTexture& backendTexture, | |
| GrSurfaceOrigin origin, | |
| int sampleCnt, | |
| SkColorType colorType, | |
| sk_sp<SkColorSpace> colorSpace, | |
| const SkSurfaceProps* surfaceProps) | |
| #In Constructors | |
| #Line # creates Surface from GPU back-end render target ## | |
| #Populate | |
| #Example | |
| #ToDo example is bogus; gpuSurface should not make image ## | |
| #Platform gpu | |
| #Image 3 | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeFromBackendTextureAsRenderTarget( | |
| context, backEndTexture, kTopLeft_GrSurfaceOrigin, 0, | |
| kRGBA_8888_SkColorType, nullptr, nullptr); | |
| auto surfaceCanvas = gpuSurface->getCanvas(); | |
| surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, | |
| const SkImageInfo& imageInfo, | |
| int sampleCount, GrSurfaceOrigin surfaceOrigin, | |
| const SkSurfaceProps* surfaceProps, | |
| bool shouldCreateWithMips = false) | |
| #In Constructors | |
| #Line # creates Surface pointing to new GPU memory buffer ## | |
| #Populate | |
| #Example | |
| #Platform gpu | |
| #Height 64 | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType); | |
| for (auto surfaceOrigin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin } ) { | |
| auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0, | |
| surfaceOrigin, nullptr)); | |
| auto surfaceCanvas = gpuSurface->getCanvas(); | |
| surfaceCanvas->clear(SK_ColorWHITE); | |
| surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| canvas->translate(0, 128); | |
| } | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, | |
| const SkImageInfo& imageInfo, int sampleCount, | |
| const SkSurfaceProps* props) | |
| #Populate | |
| #Example | |
| #Platform cpu gpu | |
| #Description | |
| LCD text takes advantage of raster striping to improve resolution. Only one of | |
| the four combinations is correct, depending on whether monitor LCD striping is | |
| horizontal or vertical, and whether the order of the stripes is red blue green | |
| or red green blue. | |
| ## | |
| void draw(SkCanvas* canvas) { | |
| auto test_draw = [](SkCanvas* surfaceCanvas) -> void { | |
| SkPaint paint; | |
| paint.setAntiAlias(true); | |
| paint.setLCDRenderText(true); | |
| paint.setColor(0xFFBBBBBB); | |
| surfaceCanvas->drawRect(SkRect::MakeWH(128, 64), paint); | |
| paint.setColor(SK_ColorWHITE); | |
| paint.setTextSize(32); | |
| surfaceCanvas->drawString("Pest", 0, 25, paint); | |
| }; | |
| GrContext* context = canvas->getGrContext(); | |
| SkImageInfo info = SkImageInfo::MakeN32(128, 64, kOpaque_SkAlphaType); | |
| int y = 0; | |
| for (auto geometry : { kRGB_H_SkPixelGeometry, kBGR_H_SkPixelGeometry, | |
| kRGB_V_SkPixelGeometry, kBGR_V_SkPixelGeometry } ) { | |
| SkSurfaceProps props(0, geometry); | |
| sk_sp<SkSurface> surface = context ? SkSurface::MakeRenderTarget( | |
| context, SkBudgeted::kNo, info, 0, &props) : SkSurface::MakeRaster(info, &props); | |
| test_draw(surface->getCanvas()); | |
| surface->draw(canvas, 0, y, nullptr); | |
| sk_sp<SkImage> image(surface->makeImageSnapshot()); | |
| SkAutoCanvasRestore acr(canvas, true); | |
| canvas->scale(8, 8); | |
| canvas->drawImage(image, 12, y / 8); | |
| y += 64; | |
| } | |
| } | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted, | |
| const SkImageInfo& imageInfo) | |
| #Populate | |
| #Example | |
| #Platform gpu | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| SkImageInfo info = SkImageInfo::MakeN32(256, 64, kOpaque_SkAlphaType); | |
| auto gpuSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info)); | |
| auto surfaceCanvas = gpuSurface->getCanvas(); | |
| surfaceCanvas->clear(SK_ColorWHITE); | |
| surfaceCanvas->drawString("GPU rocks!", 20, 40, paint); | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context, | |
| const SkSurfaceCharacterization& characterization, | |
| SkBudgeted budgeted) | |
| #Populate | |
| #NoExample | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeNull(int width, int height) | |
| #In Constructors | |
| #Line # creates Surface without backing pixels ## | |
| #Populate | |
| #Example | |
| SkDebugf("SkSurface::MakeNull(0, 0) %c= nullptr\n", SkSurface::MakeNull(0, 0) == nullptr ? | |
| '=' : '!'); | |
| const int w = 37; | |
| const int h = 1000; | |
| auto surf = SkSurface::MakeNull(w, h); | |
| auto nullCanvas = surf->getCanvas(); | |
| nullCanvas->drawPaint(SkPaint()); // does not crash, nothing draws | |
| SkDebugf("surf->makeImageSnapshot() %c= nullptr\n", surf->makeImageSnapshot() == nullptr ? | |
| '=' : '!'); | |
| #StdOut | |
| SkSurface::MakeNull(0, 0) == nullptr | |
| surf->makeImageSnapshot() == nullptr | |
| ## | |
| ## | |
| #SeeAlso MakeRaster MakeRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Property | |
| #Line # member values ## | |
| ## | |
| #Method int width() const | |
| #In Property | |
| #Line # returns pixel column count ## | |
| #Populate | |
| #Example | |
| const int width = 37; | |
| const int height = 1000; | |
| auto surf = SkSurface::MakeNull(width, height); | |
| auto nullCanvas = surf->getCanvas(); | |
| SkDebugf("surface width=%d canvas width=%d\n", surf->width(), | |
| nullCanvas->getBaseLayerSize().fWidth); | |
| #StdOut | |
| surface width=37 canvas width=37 | |
| ## | |
| ## | |
| #SeeAlso height() | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method int height() const | |
| #In Property | |
| #Line # returns pixel row count ## | |
| #Populate | |
| #Example | |
| const int width = 37; | |
| const int height = 1000; | |
| auto surf = SkSurface::MakeNull(width, height); | |
| auto nullCanvas = surf->getCanvas(); | |
| SkDebugf("surface height=%d canvas height=%d\n", surf->height(), | |
| nullCanvas->getBaseLayerSize().fHeight); | |
| #StdOut | |
| surface height=1000 canvas height=1000 | |
| ## | |
| ## | |
| #SeeAlso width() | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method uint32_t generationID() | |
| #In Property | |
| #Line # returns unique ID ## | |
| #Populate | |
| #Example | |
| auto surface = SkSurface::MakeRasterN32Premul(1, 1); | |
| for (int i = 0; i < 3; ++i) { | |
| SkDebugf("surface generationID: %d\n", surface->generationID()); | |
| if (0 == i) { | |
| surface->getCanvas()->drawColor(SK_ColorBLACK); | |
| } else { | |
| surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); | |
| } | |
| } | |
| #StdOut | |
| surface generationID: 1 | |
| surface generationID: 2 | |
| surface generationID: 3 | |
| ## | |
| ## | |
| #SeeAlso notifyContentWillChange ContentChangeMode getCanvas | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Enum ContentChangeMode | |
| #Line # parameter options for notifyContentWillChange ## | |
| #Code | |
| enum ContentChangeMode { | |
| kDiscard_ContentChangeMode, | |
| kRetain_ContentChangeMode, | |
| }; | |
| ## | |
| ContentChangeMode members are parameters to notifyContentWillChange. | |
| #Const kDiscard_ContentChangeMode | |
| #Line # discards surface on change ## | |
| Pass to notifyContentWillChange to discard surface contents when | |
| the surface is cleared or overwritten. | |
| ## | |
| #Const kRetain_ContentChangeMode | |
| #Line # preserves surface on change ## | |
| Pass to notifyContentWillChange when to preserve surface contents. | |
| If a snapshot has been generated, this copies the Surface contents. | |
| ## | |
| #SeeAlso notifyContentWillChange generationID | |
| #Enum ## | |
| # ------------------------------------------------------------------------------ | |
| #ToDo not crazy about misc catagory -- hopefully will become clear with time | |
| ## | |
| #Subtopic Miscellaneous | |
| #Line # other functions ## | |
| ## | |
| #Method void notifyContentWillChange(ContentChangeMode mode) | |
| #In Miscellaneous | |
| #Line # notifies that contents will be changed outside of Skia ## | |
| #Populate | |
| #Example | |
| auto surface = SkSurface::MakeRasterN32Premul(1, 1); | |
| for (int i = 0; i < 3; ++i) { | |
| SkDebugf("surface generationID: %d\n", surface->generationID()); | |
| if (0 == i) { | |
| surface->getCanvas()->drawColor(SK_ColorBLACK); | |
| } else { | |
| surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); | |
| } | |
| } | |
| ## | |
| #SeeAlso ContentChangeMode generationID | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Enum BackendHandleAccess | |
| #Line # options to read and write back-end object ## | |
| #Code | |
| enum BackendHandleAccess { | |
| kFlushRead_BackendHandleAccess, | |
| kFlushWrite_BackendHandleAccess, | |
| kDiscardWrite_BackendHandleAccess, | |
| }; | |
| static const BackendHandleAccess kFlushRead_TextureHandleAccess = | |
| kFlushRead_BackendHandleAccess; | |
| static const BackendHandleAccess kFlushWrite_TextureHandleAccess = | |
| kFlushWrite_BackendHandleAccess; | |
| static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = | |
| kDiscardWrite_BackendHandleAccess; | |
| ## | |
| #Const kFlushRead_BackendHandleAccess 0 | |
| #Line # back-end object is readable ## | |
| Caller may read from the back-end object. | |
| ## | |
| #Const kFlushWrite_BackendHandleAccess 1 | |
| #Line # back-end object is writable ## | |
| Caller may write to the back-end object. | |
| ## | |
| #Const kDiscardWrite_BackendHandleAccess 2 | |
| #Line # back-end object must be overwritten ## | |
| Caller must overwrite the entire back-end object. | |
| ## | |
| #NoExample | |
| // todo: need to update example to use GrBackendTexture instead of GrBackendObject | |
| #Platform gpu | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget( | |
| context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(10, 10)); | |
| int y = 20; | |
| SkString str; | |
| paint.setTextSize(16); | |
| for (auto access : { SkSurface::kFlushRead_BackendHandleAccess, | |
| SkSurface::kFlushWrite_BackendHandleAccess, | |
| SkSurface::kDiscardWrite_BackendHandleAccess } ) { | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| str.printf("uniqueID=%d", image->uniqueID()); | |
| canvas->drawString(str, 20, y += 20, paint); | |
| GrBackendTexture backendTex = gpuSurface->getBackendTexture(access); | |
| str.printf("backendTex is %svalid", backendTex.isValid() ? '' : 'not '); | |
| canvas->drawString(str, 20, y += 20, paint); | |
| } | |
| sk_sp<SkImage> image(gpuSurface->makeImageSnapshot()); | |
| str.printf("final image uniqueID=%d", image->uniqueID()); | |
| canvas->drawString(str, 20, y += 20, paint); | |
| ## | |
| #SeeAlso getBackendTexture getBackendRenderTarget | |
| #Enum ## | |
| # ------------------------------------------------------------------------------ | |
| #Method GrBackendTexture getBackendTexture(BackendHandleAccess backendHandleAccess) | |
| #In Property | |
| #Line # returns the GPU reference to texture ## | |
| #Populate | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendTexture BackendHandleAccess getBackendRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess) | |
| #In Property | |
| #Line # returns the GPU reference to render target ## | |
| #Populate | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendRenderTarget BackendHandleAccess getBackendTexture | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method SkCanvas* getCanvas() | |
| #In Property | |
| #Line # returns Canvas that draws into Surface ## | |
| #Populate | |
| #Example | |
| #Height 64 | |
| sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(64, 64)); | |
| SkCanvas* surfaceCanvas = surface->getCanvas(); | |
| surfaceCanvas->clear(SK_ColorBLUE); | |
| SkPaint paint; | |
| paint.setTextSize(40); | |
| surfaceCanvas->drawString("\xF0\x9F\x98\x81", 12, 45, paint); | |
| surface->draw(canvas, 0, 0, nullptr); | |
| ## | |
| #SeeAlso makeSurface makeImageSnapshot draw | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method sk_sp<SkSurface> makeSurface(const SkImageInfo& imageInfo) | |
| #In Constructors | |
| #Line # creates a compatible Surface ## | |
| #Populate | |
| #Example | |
| #Height 96 | |
| sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); | |
| sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); | |
| big->getCanvas()->clear(SK_ColorRED); | |
| lil->getCanvas()->clear(SK_ColorBLACK); | |
| SkPixmap pixmap; | |
| if (big->peekPixels(&pixmap)) { | |
| SkBitmap bigBits; | |
| bigBits.installPixels(pixmap); | |
| canvas->drawBitmap(bigBits, 0, 0); | |
| } | |
| if (lil->peekPixels(&pixmap)) { | |
| SkBitmap lilBits; | |
| lilBits.installPixels(pixmap); | |
| canvas->drawBitmap(lilBits, 64, 64); | |
| } | |
| ## | |
| #SeeAlso makeImageSnapshot getCanvas draw | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method sk_sp<SkImage> makeImageSnapshot() | |
| #In Constructors | |
| #Line # creates Image capturing Surface contents ## | |
| #Populate | |
| #Example | |
| #Height 64 | |
| sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); | |
| sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); | |
| big->getCanvas()->clear(SK_ColorRED); | |
| lil->getCanvas()->clear(SK_ColorBLACK); | |
| sk_sp<SkImage> early(big->makeImageSnapshot()); | |
| lil->draw(big->getCanvas(), 16, 16, nullptr); | |
| sk_sp<SkImage> later(big->makeImageSnapshot()); | |
| canvas->drawImage(early, 0, 0); | |
| canvas->drawImage(later, 128, 0); | |
| ## | |
| #SeeAlso draw getCanvas | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method sk_sp<SkImage> makeImageSnapshot(const SkIRect& bounds) | |
| #In Constructors | |
| #Line # creates Image capturing subset of Surface contents ## | |
| #Populate | |
| #Example | |
| #Height 64 | |
| sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); | |
| sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); | |
| big->getCanvas()->clear(SK_ColorRED); | |
| lil->getCanvas()->clear(SK_ColorBLACK); | |
| sk_sp<SkImage> early(big->makeImageSnapshot()); | |
| lil->draw(big->getCanvas(), 16, 16, nullptr); | |
| sk_sp<SkImage> later(big->makeImageSnapshot({0, 0, 16, 16})); | |
| canvas->drawImage(early, 0, 0); | |
| canvas->drawImage(later, 0, 0); | |
| ## | |
| #SeeAlso draw getCanvas | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Pixels | |
| #Line # functions with pixel access ## | |
| ## | |
| #Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) | |
| #In Pixels | |
| #Line # draws Surface contents to canvas ## | |
| #Populate | |
| #Example | |
| #Height 64 | |
| sk_sp<SkSurface> big(SkSurface::MakeRasterN32Premul(64, 64)); | |
| sk_sp<SkSurface> lil(big->makeSurface(SkImageInfo::MakeN32(32, 32, kPremul_SkAlphaType))); | |
| big->getCanvas()->clear(SK_ColorRED); | |
| lil->getCanvas()->clear(SK_ColorBLACK); | |
| lil->draw(big->getCanvas(), 16, 16, nullptr); | |
| SkPixmap pixmap; | |
| if (big->peekPixels(&pixmap)) { | |
| SkBitmap bigBits; | |
| bigBits.installPixels(pixmap); | |
| canvas->drawBitmap(bigBits, 0, 0); | |
| } | |
| ## | |
| #SeeAlso makeImageSnapshot getCanvas | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool peekPixels(SkPixmap* pixmap) | |
| #In Pixels | |
| #Line # copies Surface parameters to Pixmap ## | |
| #Populate | |
| #Example | |
| #Height 64 | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorRED); | |
| SkPaint paint; | |
| paint.setTextSize(40); | |
| surfCanvas->drawString("&", 16, 48, paint); | |
| SkPixmap pixmap; | |
| if (surf->peekPixels(&pixmap)) { | |
| SkBitmap surfBits; | |
| surfBits.installPixels(pixmap); | |
| canvas->drawBitmap(surfBits, 0, 0); | |
| } | |
| ## | |
| #SeeAlso readPixels writePixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool readPixels(const SkPixmap& dst, int srcX, int srcY) | |
| #In Pixels | |
| #Line # copies Rect of pixels ## | |
| Copies Rect of pixels to dst. | |
| Source Rect corners are (srcX, srcY) and Surface (width(), height()). | |
| Destination Rect corners are (0, 0) and (dst.width(), dst.height()). | |
| Copies each readable pixel intersecting both rectangles, without scaling, | |
| converting to dst.colorType() and dst.alphaType() if required. | |
| Pixels are readable when Surface is raster, or backed by a GPU. | |
| The destination pixel storage must be allocated by the caller. | |
| Pixel values are converted only if Color_Type and Alpha_Type | |
| do not match. Only pixels within both source and destination rectangles | |
| are copied. dst contents outside Rect intersection are unchanged. | |
| Pass negative values for srcX or srcY to offset pixels across or down destination. | |
| Does not copy, and returns false if: | |
| #List | |
| # Source and destination rectangles do not intersect. ## | |
| # Pixmap pixels could not be allocated. ## | |
| # dst.rowBytes() is too small to contain one row of pixels. ## | |
| ## | |
| #Param dst storage for pixels copied from Surface ## | |
| #Param srcX offset into readable pixels on x-axis; may be negative ## | |
| #Param srcY offset into readable pixels on y-axis; may be negative ## | |
| #Return true if pixels were copied ## | |
| #Example | |
| #Height 32 | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorRED); | |
| SkPaint paint; | |
| paint.setTextSize(40); | |
| surfCanvas->drawString("&", 0, 32, paint); | |
| std::vector<SkPMColor> storage; | |
| storage.resize(surf->width() * surf->height()); | |
| SkPixmap pixmap(SkImageInfo::MakeN32Premul(32, 32), &storage.front(), | |
| surf->width() * sizeof(storage[0])); | |
| if (surf->readPixels(pixmap, 0, 0)) { | |
| SkBitmap surfBits; | |
| surfBits.installPixels(pixmap); | |
| canvas->drawBitmap(surfBits, 0, 0); | |
| } | |
| ## | |
| #SeeAlso peekPixels writePixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, | |
| int srcX, int srcY) | |
| Copies Rect of pixels from Canvas into dstPixels. | |
| Source Rect corners are (srcX, srcY) and Surface (width(), height()). | |
| Destination Rect corners are (0, 0) and (dstInfo.width(), dstInfo.height()). | |
| Copies each readable pixel intersecting both rectangles, without scaling, | |
| converting to dstInfo.colorType() and dstInfo.alphaType() if required. | |
| Pixels are readable when Surface is raster, or backed by a GPU. | |
| The destination pixel storage must be allocated by the caller. | |
| Pixel values are converted only if Color_Type and Alpha_Type | |
| do not match. Only pixels within both source and destination rectangles | |
| are copied. dstPixels contents outside Rect intersection are unchanged. | |
| Pass negative values for srcX or srcY to offset pixels across or down destination. | |
| Does not copy, and returns false if: | |
| #List | |
| # Source and destination rectangles do not intersect. ## | |
| # Surface pixels could not be converted to dstInfo.colorType() or dstInfo.alphaType(). ## | |
| # dstRowBytes is too small to contain one row of pixels. ## | |
| ## | |
| #Param dstInfo width, height, Color_Type, and Alpha_Type of dstPixels ## | |
| #Param dstPixels storage for pixels; dstInfo.height() times dstRowBytes, or larger ## | |
| #Param dstRowBytes size of one destination row; dstInfo.width() times pixel size, or larger ## | |
| #Param srcX offset into readable pixels on x-axis; may be negative ## | |
| #Param srcY offset into readable pixels on y-axis; may be negative ## | |
| #Return true if pixels were copied ## | |
| #Example | |
| #Height 64 | |
| #Description | |
| A black oval drawn on a red background provides an image to copy. | |
| readPixels copies one quarter of the Surface into each of the four corners. | |
| The copied quarter ovals overdraw the original oval. | |
| ## | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorRED); | |
| SkPaint paint; | |
| surfCanvas->drawOval({4, 8, 58, 54}, paint); | |
| SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType); | |
| sk_sp<SkData> data(SkData::MakeUninitialized(info.minRowBytes() * info.height())); | |
| sk_bzero(data->writable_data(), info.minRowBytes() * info.height()); | |
| for (int x : { 32, -32 } ) { | |
| for (int y : { 32, -32 } ) { | |
| surf->readPixels(info, data->writable_data(), info.minRowBytes(), x, y); | |
| } | |
| } | |
| sk_sp<SkImage> image = SkImage::MakeRasterData(info, data, info.minRowBytes()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso peekPixels writePixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool readPixels(const SkBitmap& dst, int srcX, int srcY) | |
| Copies Rect of pixels from Surface into bitmap. | |
| Source Rect corners are (srcX, srcY) and Surface (width(), height()). | |
| Destination Rect corners are (0, 0) and (bitmap.width(), bitmap.height()). | |
| Copies each readable pixel intersecting both rectangles, without scaling, | |
| converting to dst.colorType() and dst.alphaType() if required. | |
| Pixels are readable when Surface is raster, or backed by a GPU. | |
| The destination pixel storage must be allocated by the caller. | |
| Pixel values are converted only if Color_Type and Alpha_Type | |
| do not match. Only pixels within both source and destination rectangles | |
| are copied. dst contents outside Rect intersection are unchanged. | |
| Pass negative values for srcX or srcY to offset pixels across or down destination. | |
| Does not copy, and returns false if: | |
| #List | |
| # Source and destination rectangles do not intersect. ## | |
| # Surface pixels could not be converted to dst.colorType() or dst.alphaType(). ## | |
| # dst pixels could not be allocated. ## | |
| # dst.rowBytes() is too small to contain one row of pixels. ## | |
| ## | |
| #Param dst storage for pixels copied from Surface ## | |
| #Param srcX offset into readable pixels on x-axis; may be negative ## | |
| #Param srcY offset into readable pixels on y-axis; may be negative ## | |
| #Return true if pixels were copied ## | |
| #Example | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorGREEN); | |
| SkPaint paint; | |
| surfCanvas->drawOval({2, 10, 58, 54}, paint); | |
| SkImageInfo info = SkImageInfo::Make(64, 64, kBGRA_8888_SkColorType, kPremul_SkAlphaType); | |
| SkBitmap bitmap; | |
| bitmap.setInfo(info); | |
| bitmap.allocPixels(); | |
| for (int x : { 32, -32 } ) { | |
| for (int y : { 32, -32 } ) { | |
| surf->readPixels(bitmap, x, y); | |
| } | |
| } | |
| canvas->drawBitmap(bitmap, 0, 0); | |
| ## | |
| #SeeAlso peekPixels writePixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method void writePixels(const SkPixmap& src, int dstX, int dstY) | |
| #In Pixels | |
| #Line # copies Rect of pixels ## | |
| Copies Rect of pixels from the src Pixmap to the Surface. | |
| Source Rect corners are (0, 0) and (src.width(), src.height()). | |
| Destination Rect corners are (dstX, dstY) and | |
| #Formula # (dstX + Surface width(), dstY + Surface height()) ##. | |
| Copies each readable pixel intersecting both rectangles, without scaling, | |
| converting to Surface SkColorType and SkAlphaType if required. | |
| #Param src storage for pixels to copy to Surface ## | |
| #Param dstX x-axis position relative to Surface to begin copy; may be negative ## | |
| #Param dstY y-axis position relative to Surface to begin copy; may be negative ## | |
| #Example | |
| #Image 4 | |
| #Height 96 | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorRED); | |
| SkPaint paint; | |
| paint.setTextSize(40); | |
| surfCanvas->drawString("&", 16, 40, paint); | |
| SkPixmap pixmap; | |
| if (surf->peekPixels(&pixmap)) { | |
| surf->writePixels(pixmap, 25, 25); | |
| sk_sp<SkImage> image(surf->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| } | |
| ## | |
| #SeeAlso readPixels peekPixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method void writePixels(const SkBitmap& src, int dstX, int dstY) | |
| Copies Rect of pixels from the src Bitmap to the Surface. | |
| Source Rect corners are (0, 0) and (src.width(), src.height()). | |
| Destination Rect corners are (dstX, dstY) and | |
| #Formula # (dstX + Surface width(), dstY + Surface height()) ##. | |
| Copies each readable pixel intersecting both rectangles, without scaling, | |
| converting to Surface SkColorType and SkAlphaType if required. | |
| #Param src storage for pixels to copy to Surface ## | |
| #Param dstX x-axis position relative to Surface to begin copy; may be negative ## | |
| #Param dstY y-axis position relative to Surface to begin copy; may be negative ## | |
| #Example | |
| #Image 4 | |
| #Height 96 | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| auto surfCanvas = surf->getCanvas(); | |
| surfCanvas->clear(SK_ColorGREEN); | |
| surf->writePixels(source, 25, 25); | |
| sk_sp<SkImage> image(surf->makeImageSnapshot()); | |
| canvas->drawImage(image, 0, 0); | |
| ## | |
| #SeeAlso readPixels peekPixels | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method const SkSurfaceProps& props() const | |
| #In Property | |
| #Line # returns Surface_Properties ## | |
| #Populate | |
| #Example | |
| const char* names[] = { "Unknown", "RGB_H", "BGR_H", "RGB_V", "BGR_V" }; | |
| sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64)); | |
| SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]); | |
| #StdOut | |
| surf.props(): kRGB_H_SkPixelGeometry | |
| ## | |
| ## | |
| #SeeAlso SkSurfaceProps | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Utility | |
| #Line # rarely called management functions ## | |
| ## | |
| #Method void flush() | |
| #In Utility | |
| #Line # resolves pending I/O ## | |
| #Populate | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendSemaphore | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, | |
| GrBackendSemaphore signalSemaphores[]) | |
| #In Utility | |
| #Line # resolves pending I/O, and signal ## | |
| #Populate | |
| #NoExample | |
| ## | |
| #SeeAlso wait GrBackendSemaphore | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) | |
| #In Utility | |
| #Line # pauses commands until signaled ## | |
| #Populate | |
| #NoExample | |
| #ToDo this is copy and paste silliness masquerading as an example. Probably need gpu | |
| globals and definitely need gpu expertise to make a real example out of this | |
| also, note need to replace GrBackendObject with GrBackendTexture | |
| ## | |
| #Platform gpu | |
| #Height 64 | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| GrBackendSemaphore semaphore; | |
| sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget( | |
| context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64)); | |
| surface->flushAndSignalSemaphores(1, &semaphore); | |
| sk_sp<SkImage> image = surface->makeImageSnapshot(); | |
| GrBackendTexture backendTex = image->getBackendTexture(false); // unused | |
| SkASSERT(backendTex.isValid()); | |
| const SkImageInfo childImageInfo = SkImageInfo::Make(64, 64, | |
| kRGBA_8888_SkColorType, kPremul_SkAlphaType); | |
| sk_sp<SkSurface> childSurface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, | |
| childImageInfo, 0, kTopLeft_GrSurfaceOrigin, nullptr)); | |
| GrBackendTexture backendTexture; | |
| sk_sp<SkImage> childImage = SkImage::MakeFromTexture(context, | |
| backendTexture, // undefined | |
| kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, nullptr); | |
| SkCanvas* childCanvas = childSurface->getCanvas(); | |
| childCanvas->clear(SK_ColorRED); | |
| childSurface->wait(1, &semaphore); | |
| childCanvas->drawImage(childImage, 32, 0); | |
| childSurface->draw(canvas, 0, 0, nullptr); | |
| ## | |
| #SeeAlso flushAndSignalSemaphores GrBackendSemaphore | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool characterize(SkSurfaceCharacterization* characterization) const | |
| #In Utility | |
| #Line # sets Surface_Characterization for threaded GPU processing ## | |
| #Populate | |
| #Example | |
| #Platform gpu | |
| #Height 64 | |
| SkPaint paint; | |
| paint.setTextSize(32); | |
| GrContext* context = canvas->getGrContext(); | |
| if (!context) { | |
| canvas->drawString("GPU only!", 20, 40, paint); | |
| return; | |
| } | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeRenderTarget( | |
| context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64)); | |
| SkSurfaceCharacterization characterization; | |
| if (!gpuSurface->characterize(&characterization)) { | |
| canvas->drawString("characterization unsupported", 20, 40, paint); | |
| return; | |
| } | |
| // start of threadable work | |
| SkDeferredDisplayListRecorder recorder(characterization); | |
| SkCanvas* subCanvas = recorder.getCanvas(); | |
| subCanvas->clear(SK_ColorGREEN); | |
| std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach(); | |
| // end of threadable work | |
| gpuSurface->draw(displayList.get()); | |
| sk_sp<SkImage> img = gpuSurface->makeImageSnapshot(); | |
| canvas->drawImage(std::move(img), 0, 0); | |
| ## | |
| #SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool draw(SkDeferredDisplayList* deferredDisplayList) | |
| #Populate | |
| #Example | |
| #Height 64 | |
| #Platform gpu cpu | |
| SkPaint paint; | |
| paint.setTextSize(16); | |
| sk_sp<SkSurface> gpuSurface = SkSurface::MakeRasterN32Premul(64, 64); | |
| SkSurfaceCharacterization characterization; | |
| if (!gpuSurface->characterize(&characterization)) { | |
| canvas->drawString("characterization unsupported", 20, 40, paint); | |
| return; | |
| } | |
| // start of threadable work | |
| SkDeferredDisplayListRecorder recorder(characterization); | |
| SkCanvas* subCanvas = recorder.getCanvas(); | |
| subCanvas->clear(SK_ColorGREEN); | |
| std::unique_ptr<SkDeferredDisplayList> displayList = recorder.detach(); | |
| // end of threadable work | |
| gpuSurface->draw(displayList.get()); | |
| sk_sp<SkImage> img = gpuSurface->makeImageSnapshot(); | |
| canvas->drawImage(std::move(img), 0, 0); | |
| ## | |
| #SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList | |
| #Method ## | |
| #Class SkSurface ## | |
| #Topic Surface ## |