| #Topic Surface | |
| #Alias Surface_Reference ## | |
| #Class SkSurface | |
| SkSurface is responsible for managing the pixels that a canvas draws into. The pixels can be | |
| allocated either in CPU memory (a raster surface) or on the GPU (a GrRenderTarget surface). | |
| SkSurface takes care of allocating a SkCanvas that will draw into the surface. Call | |
| surface->getCanvas() to use that canvas (but don't delete it, it is owned by the 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. | |
| #Subtopic Overview | |
| #Populate | |
| ## | |
| #Subtopic Constant | |
| #Populate | |
| ## | |
| #Subtopic Related_Function | |
| #Populate | |
| ## | |
| #Subtopic Member_Function | |
| #Populate | |
| ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Constructor | |
| #Populate | |
| ## | |
| #Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels, | |
| size_t rowBytes, | |
| const SkSurfaceProps* surfaceProps = nullptr) | |
| #In Constructor | |
| #Line # creates Surface from SkImageInfo and Pixel_Storage ## | |
| Allocates raster Surface. Canvas returned by Surface draws directly into pixels. | |
| Surface is returned if all parameters are valid. | |
| Valid parameters include: | |
| info dimensions are greater than zero; | |
| info contains Color_Type and Alpha_Type supported by Raster_Surface; | |
| pixels is not nullptr; | |
| rowBytes is large enough to contain info width pixels of Color_Type. | |
| Pixel buffer size should be info height times computed rowBytes. | |
| Pixels are not initialized. | |
| To access pixels after drawing, call flush() or peekPixels. | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width and height must be greater than zero | |
| ## | |
| #Param pixels pointer to destination pixels buffer ## | |
| #Param rowBytes interval from one Surface row to the next ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent fonts; | |
| may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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 Constructor | |
| #Line # creates Surface from SkImageInfo and Pixel_Storage ## | |
| Allocates raster Surface. Canvas returned by Surface draws directly into pixels. | |
| releaseProc is called with pixels and context when Surface is deleted. | |
| Surface is returned if all parameters are valid. | |
| Valid parameters include: | |
| info dimensions are greater than zero; | |
| info contains Color_Type and Alpha_Type supported by Raster_Surface; | |
| pixels is not nullptr; | |
| rowBytes is large enough to contain info width pixels of Color_Type. | |
| Pixel buffer size should be info height times computed rowBytes. | |
| Pixels are not initialized. | |
| To access pixels after drawing, call flush() or peekPixels. | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width and height must be greater than zero | |
| ## | |
| #Param pixels pointer to destination pixels buffer ## | |
| #Param rowBytes interval from one Surface row to the next ## | |
| #Param releaseProc called when Surface is deleted; may be nullptr ## | |
| #Param context passed to releaseProc; may be nullptr ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent fonts; | |
| may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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 Constructor | |
| #Line # creates Surface from SkImageInfo ## | |
| Allocates raster Surface. Canvas returned by Surface draws directly into pixels. | |
| Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times | |
| rowBytes, or times imageInfo.minRowBytes() if rowBytes is zero. | |
| Pixel memory is deleted when Surface is deleted. | |
| Surface is returned if all parameters are valid. | |
| Valid parameters include: | |
| info dimensions are greater than zero; | |
| info contains Color_Type and Alpha_Type supported by Raster_Surface; | |
| rowBytes is large enough to contain info width pixels of Color_Type, or is zero. | |
| If rowBytes is not zero, subsequent images returned by makeImageSnapshot | |
| have the same rowBytes. | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width and height must be greater than zero | |
| ## | |
| #Param rowBytes interval from one Surface row to the next; may be zero ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent fonts; | |
| may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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) | |
| Allocates raster Surface. Canvas returned by Surface draws directly into pixels. | |
| Allocates and zeroes pixel memory. Pixel memory size is imageInfo.height() times | |
| imageInfo.minRowBytes(). | |
| Pixel memory is deleted when Surface is deleted. | |
| Surface is returned if all parameters are valid. | |
| Valid parameters include: | |
| info dimensions are greater than zero; | |
| info contains Color_Type and Alpha_Type supported by Raster_Surface. | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width and height must be greater than zero | |
| ## | |
| #Param props LCD striping orientation and setting for device independent fonts; | |
| may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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 Constructor | |
| #Line # creates Surface from width, height matching output ## | |
| Allocates raster Surface. Canvas returned by Surface draws directly into pixels. | |
| Allocates and zeroes pixel memory. Pixel memory size is height times width times | |
| four. Pixel memory is deleted when Surface is deleted. | |
| Internally, sets Image_Info to width, height, Native_Color_Type, and | |
| kPremul_SkAlphaType. | |
| Surface is returned if width and height are greater than zero. | |
| Use to create Surface that matches SkPMColor, the native pixel arrangement on | |
| the platform. Surface drawn to output device skips converting its pixel format. | |
| #Param width pixel column count; must be greater than zero ## | |
| #Param height pixel row count; must be greater than zero ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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) | |
| #In Constructor | |
| #Line # creates Surface from GPU texture ## | |
| Wraps a GPU-backed texture into Surface. Caller must ensure the texture is | |
| valid for the lifetime of returned Surface. If sampleCnt greater than zero, | |
| creates an intermediate MSAA Surface which is used for drawing backendTexture. | |
| Surface is returned if all parameters are valid. backendTexture is valid if | |
| its pixel configuration agrees with colorSpace and context; for instance, if | |
| backendTexture has an sRGB configuration, then context must support sRGB, | |
| and colorSpace must be present. Further, backendTexture width and height must | |
| not exceed context capabilities, and the context must be able to support | |
| back-end textures. | |
| If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr. | |
| #Param context GPU_Context ## | |
| #Param backendTexture texture residing on GPU ## | |
| #Param origin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ## | |
| #Param sampleCnt samples per pixel, or 0 to disable full scene anti-aliasing ## | |
| #Param colorType one of: #list_of_color_types# | |
| ## | |
| #Param colorSpace range of colors; may be nullptr ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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) | |
| #In Constructor | |
| #Line # creates Surface from GPU render target ## | |
| Wraps a GPU-backed buffer into Surface. Caller must ensure backendRenderTarget | |
| is valid for the lifetime of returned Surface. | |
| Surface is returned if all parameters are valid. backendRenderTarget is valid if | |
| its pixel configuration agrees with colorSpace and context; for instance, if | |
| backendRenderTarget has an sRGB configuration, then context must support sRGB, | |
| and colorSpace must be present. Further, backendRenderTarget width and height must | |
| not exceed context capabilities, and the context must be able to support | |
| back-end render targets. | |
| If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr. | |
| #Param context GPU_Context ## | |
| #Param backendRenderTarget GPU intermediate memory buffer ## | |
| #Param origin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ## | |
| #Param colorType one of: #list_of_color_types# | |
| ## | |
| #Param colorSpace range of colors ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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 Constructor | |
| #Line # creates Surface from GPU back-end render target ## | |
| Wraps a GPU-backed texture into Surface. Caller must ensure backendTexture is | |
| valid for the lifetime of returned Surface. If sampleCnt greater than zero, | |
| creates an intermediate MSAA Surface which is used for drawing backendTexture. | |
| Surface is returned if all parameters are valid. backendTexture is valid if | |
| its pixel configuration agrees with colorSpace and context; for instance, if | |
| backendTexture has an sRGB configuration, then context must support sRGB, | |
| and colorSpace must be present. Further, backendTexture width and height must | |
| not exceed context capabilities. | |
| Returned Surface is available only for drawing into, and cannot generate an | |
| Image. | |
| If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr. | |
| #Param context GPU_Context ## | |
| #Param backendTexture texture residing on GPU ## | |
| #Param origin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ## | |
| #Param sampleCnt samples per pixel, or 0 to disable full scene anti-aliasing ## | |
| #Param colorType one of: #list_of_color_types# | |
| ## | |
| #Param colorSpace range of colors; may be nullptr ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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 Constructor | |
| #Line # creates Surface pointing to new GPU memory buffer ## | |
| Returns Surface on GPU indicated by context. Allocates memory for | |
| pixels, based on the width, height, and Color_Type in ImageInfo. budgeted | |
| selects whether allocation for pixels is tracked by context. imageInfo | |
| describes the pixel format in Color_Type, and transparency in | |
| Alpha_Type, and color matching in Color_Space. | |
| sampleCount requests the number of samples per pixel. | |
| Pass zero to disable Multi_Sample_Anti_Aliasing. The request is rounded | |
| up to the next supported count, or rounded down if it is larger than the | |
| maximum supported count. | |
| surfaceOrigin pins either the top-left or the bottom-left corner to the origin. | |
| shouldCreateWithMips hints that Image returned by makeImageSnapshot is Mip_Map. | |
| If SK_SUPPORT_GPU is defined as zero, has no effect and returns nullptr. | |
| #Param context GPU_Context ## | |
| #Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes ## | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space; | |
| width, or height, or both, may be zero | |
| ## | |
| #Param sampleCount samples per pixel, or 0 to disable full scene anti-aliasing ## | |
| #Param surfaceOrigin one of: kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin ## | |
| #Param surfaceProps LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Param shouldCreateWithMips hint that Surface will host Mip_Map images ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #ToDo not sure that this example is relevant; surfaceOrigin doesn't appear to do anything ## | |
| #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) | |
| Returns Surface on GPU indicated by context. Allocates memory for | |
| pixels, based on the width, height, and Color_Type in ImageInfo. budgeted | |
| selects whether allocation for pixels is tracked by context. imageInfo | |
| describes the pixel format in Color_Type, and transparency in | |
| Alpha_Type, and color matching in Color_Space. | |
| sampleCount requests the number of samples per pixel. | |
| Pass zero to disable Multi_Sample_Anti_Aliasing. The request is rounded | |
| up to the next supported count, or rounded down if it is larger than the | |
| maximum supported count. | |
| Surface bottom-left corner is pinned to the origin. | |
| #Param context GPU_Context ## | |
| #Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes ## | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width, or height, or both, may be zero | |
| ## | |
| #Param sampleCount samples per pixel, or 0 to disable Multi_Sample_Anti_Aliasing ## | |
| #Param props LCD striping orientation and setting for device independent | |
| fonts; may be nullptr | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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) | |
| Returns Surface on GPU indicated by context. Allocates memory for | |
| pixels, based on the width, height, and Color_Type in ImageInfo. budgeted | |
| selects whether allocation for pixels is tracked by context. imageInfo | |
| describes the pixel format in Color_Type, and transparency in | |
| Alpha_Type, and color matching in Color_Space. | |
| Surface bottom-left corner is pinned to the origin. | |
| #Param context GPU_Context ## | |
| #Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes ## | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Raster_Surface; width, or height, or both, may be zero | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #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(GrContext* context, | |
| const SkSurfaceCharacterization& characterization, | |
| SkBudgeted budgeted) | |
| Returns SkSurface on GPU indicated by context that is compatible with the provided | |
| characterization. budgeted selects whether allocation for pixels is tracked by context. | |
| #Param context GPU_Context ## | |
| #Param characterization description of the desired SkSurface ## | |
| #Param budgeted one of: SkBudgeted::kNo, SkBudgeted::kYes | |
| ## | |
| #Return Surface if all parameters are valid; otherwise, nullptr ## | |
| #NoExample | |
| ## | |
| #SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method static sk_sp<SkSurface> MakeNull(int width, int height) | |
| #In Constructor | |
| #Line # creates Surface without backing pixels ## | |
| Returns Surface without backing pixels. Drawing to Canvas returned from Surface | |
| has no effect. Calling makeImageSnapshot() on returned Surface returns nullptr. | |
| #Param width one or greater ## | |
| #Param height one or greater ## | |
| #Return Surface if width and height are positive; otherwise, nullptr ## | |
| #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 | |
| #Populate | |
| #Line # member values ## | |
| ## | |
| #Method int width() const | |
| #In Property | |
| #Line # returns pixel column count ## | |
| Returns pixel count in each row; may be zero or greater. | |
| #Return number of pixel columns ## | |
| #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 ## | |
| Returns pixel row count; may be zero or greater. | |
| #Return number of pixel rows ## | |
| #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 ## | |
| Returns unique value identifying the content of Surface. Returned value changes | |
| each time the content changes. Content is changed by drawing, or by calling | |
| notifyContentWillChange. | |
| #Return unique content identifier ## | |
| #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 | |
| #Populate | |
| #Line # other functions ## | |
| ## | |
| #Method void notifyContentWillChange(ContentChangeMode mode) | |
| #In Miscellaneous | |
| #Line # notifies that contents will be changed outside of Skia ## | |
| Notifies that Surface contents will be changed by code outside of Skia. | |
| Subsequent calls to generationID return a different value. | |
| mode is normally passed as kRetain_ContentChangeMode. | |
| #Private | |
| Can we deprecate this? | |
| ## | |
| #Param mode one of: kDiscard_ContentChangeMode, kRetain_ContentChangeMode ## | |
| #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. | |
| ## | |
| #Const kFlushRead_TextureHandleAccess 0 | |
| #Deprecated | |
| ## | |
| #Const kFlushWrite_TextureHandleAccess 1 | |
| #Deprecated | |
| ## | |
| #Const kDiscardWrite_TextureHandleAccess 2 | |
| #Deprecated | |
| ## | |
| #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 ## | |
| Retrieves the back-end texture. If Surface has no back-end texture, an invalid | |
| object is returned. Call GrBackendTexture::isValid to determine if the result | |
| is valid. | |
| The returned GrBackendTexture should be discarded if the Surface is drawn to or deleted. | |
| #Param backendHandleAccess one of: kFlushRead_BackendHandleAccess, | |
| kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess | |
| ## | |
| #Return GPU texture reference; invalid on failure ## | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendTexture BackendHandleAccess getBackendRenderTarget | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method GrBackendRenderTarget getBackendRenderTarget(BackendHandleAccess backendHandleAccess) | |
| #In Property | |
| #Line # returns the GPU reference to render target ## | |
| Retrieves the back-end render target. If Surface has no back-end render target, an invalid | |
| object is returned. Call GrBackendRenderTarget::isValid to determine if the result | |
| is valid. | |
| The returned GrBackendRenderTarget should be discarded if the Surface is drawn to | |
| or deleted. | |
| #Param backendHandleAccess one of: kFlushRead_BackendHandleAccess, | |
| kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess | |
| ## | |
| #Return GPU render target reference; invalid on failure ## | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendRenderTarget BackendHandleAccess getBackendTexture | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method SkCanvas* getCanvas() | |
| #In Property | |
| #Line # returns Canvas that draws into Surface ## | |
| Returns Canvas that draws into Surface. Subsequent calls return the same Canvas. | |
| Canvas returned is managed and owned by Surface, and is deleted when Surface | |
| is deleted. | |
| #Return drawing Canvas for Surface ## | |
| #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 Constructor | |
| #Line # creates a compatible Surface ## | |
| Returns a compatible Surface, or nullptr. Returned Surface contains | |
| the same raster, GPU, or null properties as the original. Returned Surface | |
| does not share the same pixels. | |
| Returns nullptr if imageInfo width or height are zero, or if imageInfo | |
| is incompatible with Surface. | |
| #Param imageInfo width, height, Color_Type, Alpha_Type, Color_Space, | |
| of Surface; width and height must be greater than zero | |
| ## | |
| #Return compatible Surface or nullptr ## | |
| #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 Constructor | |
| #Line # creates Image capturing Surface contents ## | |
| Returns Image capturing Surface contents. Subsequent drawing to Surface contents | |
| are not captured. Image allocation is accounted for if Surface was created with | |
| SkBudgeted::kYes. | |
| #Return Image initialized with Surface contents ## | |
| #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 ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Pixels | |
| #Populate | |
| #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 ## | |
| Draws Surface contents to canvas, with its top-left corner at (x, y). | |
| If Paint paint is not nullptr, apply Color_Filter, Color_Alpha, Image_Filter, | |
| Blend_Mode, and Draw_Looper. | |
| #Param canvas Canvas drawn into ## | |
| #Param x horizontal offset in Canvas ## | |
| #Param y vertical offset in Canvas ## | |
| #Param paint Paint containing Blend_Mode, Color_Filter, Image_Filter, | |
| and so on; or nullptr | |
| ## | |
| #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 ## | |
| Copies Surface pixel address, row bytes, and Image_Info to Pixmap, if address | |
| is available, and returns true. If pixel address is not available, return | |
| false and leave Pixmap unchanged. | |
| pixmap contents become invalid on any future change to Surface. | |
| #Param pixmap storage for pixel state if pixels are readable; otherwise, ignored ## | |
| #Return true if Surface has direct access to pixels ## | |
| #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 bitmap.colorType() and bitmap.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 colorType() and Surface alphaType() 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 colorType() and Surface alphaType() 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 ## | |
| Returns Surface_Properties for surface. | |
| #Return LCD striping orientation and setting for device independent fonts ## | |
| #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 ## | |
| # ------------------------------------------------------------------------------ | |
| #Method void prepareForExternalIO() | |
| #Deprecated soon | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Subtopic Utility | |
| #Populate | |
| #Line # rarely called management functions ## | |
| ## | |
| #Method void flush() | |
| #In Utility | |
| #Line # resolves pending I/O ## | |
| Issues pending Surface commands to the GPU-backed API and resolves any Surface MSAA. | |
| Skia flushes as needed, so it is not necessary to call this if Skia manages | |
| drawing and object lifetime. Call when interleaving Skia calls with native | |
| GPU calls. | |
| #NoExample | |
| ## | |
| #SeeAlso GrBackendSemaphore | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores, | |
| GrBackendSemaphore signalSemaphores[]) | |
| #In Utility | |
| #Line # resolves pending I/O, and signal ## | |
| Issues pending Surface commands to the GPU-backed API and resolves any Surface MSAA. | |
| After issuing all commands, signalSemaphores of count numSemaphores semaphores | |
| are signaled by the GPU. | |
| For each GrBackendSemaphore in signalSemaphores: | |
| if GrBackendSemaphore is initialized, the GPU back-end uses the semaphore as is; | |
| otherwise, a new semaphore is created and initializes GrBackendSemaphore. | |
| The caller must delete the semaphores created and returned in signalSemaphores. | |
| GrBackendSemaphore can be deleted as soon as this function returns. | |
| If the back-end API is OpenGL only uninitialized Backend_Semaphores are supported. | |
| If the back-end API is Vulkan semaphores may be initialized or uninitialized. | |
| If uninitialized, created semaphores are valid only with the VkDevice | |
| with which they were created. | |
| If GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not create or | |
| add any semaphores to signal on the GPU; the caller should not instruct the GPU | |
| to wait on any of the semaphores. | |
| Pending surface commands are flushed regardless of the return result. | |
| #Param numSemaphores size of signalSemaphores array ## | |
| #Param signalSemaphores array of semaphore containers ## | |
| #Return one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo ## | |
| #NoExample | |
| ## | |
| #SeeAlso wait GrBackendSemaphore | |
| #Method ## | |
| # ------------------------------------------------------------------------------ | |
| #Method bool wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) | |
| #In Utility | |
| #Line # pauses commands until signaled ## | |
| Inserts a list of GPU semaphores that the current GPU-backed API must wait on before | |
| executing any more commands on the GPU for this surface. Skia will take ownership of the | |
| underlying semaphores and delete them once they have been signaled and waited on. | |
| If this call returns false, then the GPU back-end will not wait on any passed in semaphores, | |
| and the client will still own the semaphores. | |
| #Param numSemaphores size of waitSemaphores array ## | |
| #Param waitSemaphores array of semaphore containers ## | |
| #Return true if GPU is waiting on semaphores ## | |
| #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 ## | |
| Initializes Surface_Characterization that can be used to perform GPU back-end | |
| processing in a separate thread. Typically this is used to divide drawing | |
| into multiple tiles. DeferredDisplayListRecorder records the drawing commands | |
| for each tile. | |
| Return true if Surface supports characterization. Raster_Surface returns false. | |
| #Param characterization properties for parallel drawing ## | |
| #Return true if supported ## | |
| #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) | |
| Draws deferred display list created using SkDeferredDisplayListRecorder. | |
| Has no effect and returns false if Surface_Characterization stored in | |
| deferredDisplayList is not compatible with Surface. | |
| Raster_Surface returns false. | |
| #Param deferredDisplayList drawing commands ## | |
| #Return false if deferredDisplayList is not compatible ## | |
| #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 ## |