2017-11-27 15:44:06 +00:00
|
|
|
#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.
|
|
|
|
|
|
|
|
#Topic Overview
|
|
|
|
|
|
|
|
#Subtopic Subtopics
|
|
|
|
#ToDo manually add subtopics ##
|
|
|
|
#Table
|
|
|
|
#Legend
|
|
|
|
# topics # description ##
|
|
|
|
#Legend ##
|
|
|
|
#Table ##
|
|
|
|
##
|
|
|
|
|
|
|
|
#Subtopic Member_Functions
|
|
|
|
#Table
|
|
|
|
#Legend
|
|
|
|
# description # function ##
|
|
|
|
#Legend ##
|
|
|
|
# MakeFromBackendRenderTarget # Creates Surface from GPU memory buffer. ##
|
|
|
|
# MakeFromBackendTexture # Creates Surface from GPU-backed texture. ##
|
|
|
|
# MakeFromBackendTextureAsRenderTarget # Creates Surface from GPU-backed texture. ##
|
|
|
|
# MakeNull # Creates Surface without backing pixels. ##
|
|
|
|
# MakeRaster # Creates Surface from SkImageInfo. ##
|
|
|
|
# MakeRasterDirect # Creates Surface from SkImageInfo and Pixel_Storage. ##
|
|
|
|
# MakeRasterDirectReleaseProc # Creates Surface from SkImageInfo and Pixel_Storage. ##
|
|
|
|
# MakeRasterN32Premul # Creates Surface from width, height matching output. ##
|
|
|
|
# MakeRenderTarget # Creates Surface pointing to new GPU memory buffer. ##
|
|
|
|
# characterize() # Set up Surface_Characterization for threaded pre-processing. ##
|
|
|
|
# draw() # Draws Surface contents to canvas. ##
|
|
|
|
# flush() # Resolve pending I/O. ##
|
|
|
|
# flushAndSignalSemaphores # Resolve pending I/O, and signal. ##
|
|
|
|
# generationID # Returns unique ID. ##
|
|
|
|
# getCanvas # Returns Canvas that draws into Surface. ##
|
|
|
|
# getRenderTargetHandle # Returns the GPU reference to render target. ##
|
|
|
|
# getTextureHandle # Returns the GPU reference to texture. ##
|
|
|
|
# height() # Returns pixel row count. ##
|
|
|
|
# makeImageSnapshot # Returns Image capturing Surface contents. ##
|
|
|
|
# makeSurface # Returns a compatible Surface. ##
|
|
|
|
# notifyContentWillChange # Notifies that contents will be changed outside of Skia. ##
|
|
|
|
# peekPixels # Copies Surface parameters to Pixmap. ##
|
|
|
|
# prepareForExternalIO # To be deprecated. ##
|
|
|
|
# props() # Returns Surface_Properties. ##
|
|
|
|
# readPixels # Copies Rect of pixels. ##
|
|
|
|
# wait() # Pause commands until signaled. ##
|
|
|
|
# width() # Returns pixel column count. ##
|
|
|
|
#Table ##
|
|
|
|
#Subtopic ##
|
|
|
|
|
|
|
|
#Topic ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method static sk_sp<SkSurface> MakeRasterDirect(const SkImageInfo& imageInfo, void* pixels,
|
|
|
|
size_t rowBytes,
|
|
|
|
const SkSurfaceProps* surfaceProps = nullptr)
|
|
|
|
|
|
|
|
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 Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
|
|
|
|
pixels is not nullptr;
|
|
|
|
rowBytes is large enough to contain info width pixels of Image_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, Image_Color_Type, Image_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)
|
|
|
|
|
|
|
|
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 Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
|
|
|
|
pixels is not nullptr;
|
|
|
|
rowBytes is large enough to contain info width pixels of Image_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, Image_Color_Type, Image_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)
|
|
|
|
|
|
|
|
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 Image_Color_Type and Image_Alpha_Type supported by Raster_Surface;
|
|
|
|
rowBytes is large enough to contain info width pixels of Image_Color_Type, or is zero.
|
|
|
|
|
|
|
|
If rowBytes is not zero, subsequent images returned by makeImageSnapshot
|
|
|
|
have the same rowBytes.
|
|
|
|
|
|
|
|
#Param imageInfo width, height, Image_Color_Type, Image_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 Image_Color_Type and Image_Alpha_Type supported by Raster_Surface.
|
|
|
|
|
|
|
|
#Param imageInfo width, height, Image_Color_Type, Image_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)
|
|
|
|
|
|
|
|
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,
|
|
|
|
sk_sp<SkColorSpace> colorSpace,
|
|
|
|
const SkSurfaceProps* surfaceProps)
|
|
|
|
|
|
|
|
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 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 cpu
|
|
|
|
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,
|
|
|
|
backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin, 0, nullptr, 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);
|
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso GrBackendTexture MakeFromBackendRenderTarget MakeRenderTarget
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrContext* context,
|
|
|
|
const GrBackendRenderTarget& backendRenderTarget,
|
|
|
|
GrSurfaceOrigin origin,
|
|
|
|
sk_sp<SkColorSpace> colorSpace,
|
|
|
|
const SkSurfaceProps* surfaceProps)
|
|
|
|
|
|
|
|
Wraps a GPU-backed buffer into Surface. Caller must ensure render target 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 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, nullptr, 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);
|
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso MakeFromBackendTexture MakeRenderTarget
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method static sk_sp<SkSurface> MakeFromBackendTextureAsRenderTarget(GrContext* context,
|
|
|
|
const GrBackendTexture& backendTexture,
|
|
|
|
GrSurfaceOrigin origin,
|
|
|
|
int sampleCnt,
|
|
|
|
sk_sp<SkColorSpace> colorSpace,
|
|
|
|
const SkSurfaceProps* surfaceProps)
|
|
|
|
|
|
|
|
Used to wrap a GPU-backed texture as a SkSurface. Skia will treat the texture as
|
|
|
|
a rendering target only, but unlike NewFromBackendRenderTarget, Skia will manage and own
|
|
|
|
the associated render target objects (but not the provided texture). Skia will not assume
|
|
|
|
ownership of the texture and the client must ensure the texture is valid for the lifetime
|
|
|
|
of the SkSurface.
|
|
|
|
|
|
|
|
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 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
|
|
|
|
#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::MakeFromBackendTextureAsRenderTarget(
|
|
|
|
context, backEndTextureRenderTarget, kTopLeft_GrSurfaceOrigin, 0,
|
|
|
|
nullptr, 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);
|
|
|
|
##
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
|
|
|
Returns offscreen Surface on GPU indicated by context. Allocates memory for
|
|
|
|
pixels, based on the width, height, and Image_Color_Type in ImageInfo. budgeted
|
|
|
|
selects whether allocation for offscreen pixels is tracked by context. imageInfo
|
|
|
|
describes the pixel format in Image_Color_Type, and transparency in
|
|
|
|
Image_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, Image_Color_Type, Image_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 offscreen Surface on GPU indicated by context. Allocates memory for
|
|
|
|
pixels, based on the width, height, and Image_Color_Type in ImageInfo. budgeted
|
|
|
|
selects whether allocation for offscreen pixels is tracked by context. imageInfo
|
|
|
|
describes the pixel format in Image_Color_Type, and transparency in
|
|
|
|
Image_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, Image_Color_Type, Image_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
|
2017-12-01 16:49:58 +00:00
|
|
|
#Platform cpu gpu
|
2017-11-27 15:44:06 +00:00
|
|
|
#Description
|
|
|
|
LCD text takes advantage of raster striping to improve resolution. Only one of
|
|
|
|
the four combinations is correct, depending on whether the monitor's LCD 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);
|
2017-12-01 16:49:58 +00:00
|
|
|
sk_sp<SkImage> image(surface->makeImageSnapshot());
|
2017-11-27 15:44:06 +00:00
|
|
|
SkAutoCanvasRestore acr(canvas, true);
|
|
|
|
canvas->scale(8, 8);
|
2017-12-01 16:49:58 +00:00
|
|
|
canvas->drawImage(image, 12, y / 8);
|
2017-11-27 15:44:06 +00:00
|
|
|
y += 64;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso MakeFromBackendRenderTarget MakeFromBackendTextureAsRenderTarget
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method static sk_sp<SkSurface> MakeRenderTarget(GrContext* context, SkBudgeted budgeted,
|
|
|
|
const SkImageInfo& imageInfo)
|
|
|
|
|
|
|
|
Returns offscreen Surface on GPU indicated by context. Allocates memory for
|
|
|
|
pixels, based on the width, height, and Image_Color_Type in ImageInfo. budgeted
|
|
|
|
selects whether allocation for offscreen pixels is tracked by context. imageInfo
|
|
|
|
describes the pixel format in Image_Color_Type, and transparency in
|
|
|
|
Image_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, Image_Color_Type, Image_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> MakeNull(int width, int height)
|
|
|
|
|
|
|
|
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 ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method int width() const
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
#Code
|
|
|
|
enum ContentChangeMode {
|
|
|
|
kDiscard_ContentChangeMode,
|
|
|
|
kRetain_ContentChangeMode,
|
|
|
|
};
|
|
|
|
##
|
|
|
|
|
|
|
|
ContentChangeMode members are parameters to notifyContentWillChange.
|
|
|
|
|
|
|
|
#Const kDiscard_ContentChangeMode
|
|
|
|
Pass to notifyContentWillChange to discard surface contents when
|
|
|
|
the surface is cleared or overwritten.
|
|
|
|
##
|
|
|
|
#Const kRetain_ContentChangeMode
|
|
|
|
Pass to notifyContentWillChange when to preserve surface contents.
|
|
|
|
If a snapshot has been generated, this copies the Surface contents.
|
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso notifyContentWillChange generationID
|
|
|
|
|
|
|
|
#Enum ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method void notifyContentWillChange(ContentChangeMode mode)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
#Code
|
|
|
|
enum BackendHandleAccess {
|
|
|
|
kFlushRead_BackendHandleAccess,
|
|
|
|
kFlushWrite_BackendHandleAccess,
|
|
|
|
kDiscardWrite_BackendHandleAccess,
|
|
|
|
};
|
|
|
|
##
|
|
|
|
|
2017-12-01 16:49:58 +00:00
|
|
|
#Const kFlushRead_BackendHandleAccess 0
|
2017-11-27 15:44:06 +00:00
|
|
|
Caller may read from the back-end object.
|
|
|
|
##
|
2017-12-01 16:49:58 +00:00
|
|
|
#Const kFlushWrite_BackendHandleAccess 1
|
2017-11-27 15:44:06 +00:00
|
|
|
Caller may write to the back-end object.
|
|
|
|
##
|
2017-12-01 16:49:58 +00:00
|
|
|
#Const kDiscardWrite_BackendHandleAccess 2
|
2017-11-27 15:44:06 +00:00
|
|
|
Caller must overwrite the entire back-end object.
|
|
|
|
##
|
|
|
|
|
|
|
|
#Example
|
|
|
|
#Platform gpu
|
2017-12-01 16:49:58 +00:00
|
|
|
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);
|
|
|
|
GrBackendObject backendObject = gpuSurface->getTextureHandle(access);
|
|
|
|
str.printf("backendObject %c= 0", backendObject != 0 ? '!' : '=');
|
|
|
|
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);
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso getTextureHandle getRenderTargetHandle
|
|
|
|
|
|
|
|
#Enum ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method GrBackendObject getTextureHandle(BackendHandleAccess backendHandleAccess)
|
|
|
|
|
|
|
|
Returns the GPU back-end reference of the texture used by Surface, or zero
|
|
|
|
if Surface is not backed by a GPU texture.
|
|
|
|
|
|
|
|
The returned texture handle is only valid until the next draw into Surface,
|
|
|
|
or when Surface is deleted.
|
|
|
|
|
|
|
|
#Param backendHandleAccess one of: kFlushRead_BackendHandleAccess,
|
|
|
|
kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess
|
|
|
|
##
|
|
|
|
|
|
|
|
#Return GPU texture reference ##
|
|
|
|
|
|
|
|
#Example
|
|
|
|
#Platform gpu
|
|
|
|
#Height 64
|
2017-12-01 16:49:58 +00:00
|
|
|
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));
|
|
|
|
GrBackendObject backendObject = gpuSurface->getTextureHandle(
|
|
|
|
SkSurface::kFlushRead_BackendHandleAccess);
|
|
|
|
if (backendObject) {
|
|
|
|
SkString str;
|
|
|
|
str.printf("backendObject=%08x", backendObject);
|
|
|
|
paint.setTextSize(16);
|
|
|
|
canvas->drawString(str, 20, 40, paint);
|
|
|
|
}
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso getRenderTargetHandle GrBackendObject BackendHandleAccess
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method bool getRenderTargetHandle(GrBackendObject* backendObject,
|
|
|
|
BackendHandleAccess backendHandleAccess)
|
|
|
|
|
|
|
|
Returns true and stores the GPU back-end reference of the render target used
|
|
|
|
by Surface in backendObject.
|
|
|
|
|
|
|
|
Return false if Surface is not backed by a GPU render target, and leaves
|
|
|
|
backendObject unchanged.
|
|
|
|
|
|
|
|
The returned render target handle is only valid until the next draw into Surface,
|
|
|
|
or when Surface is deleted.
|
|
|
|
|
|
|
|
In OpenGL this returns the frame buffer object ID.
|
|
|
|
|
|
|
|
#Param backendObject GPU intermediate memory buffer ##
|
|
|
|
#Param backendHandleAccess one of: kFlushRead_BackendHandleAccess,
|
|
|
|
kFlushWrite_BackendHandleAccess, kDiscardWrite_BackendHandleAccess
|
|
|
|
##
|
|
|
|
|
|
|
|
#Return true if Surface is backed by GPU texture ##
|
|
|
|
|
|
|
|
#Example
|
|
|
|
#Platform gpu
|
|
|
|
#Height 64
|
2017-12-01 16:49:58 +00:00
|
|
|
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));
|
|
|
|
GrBackendObject backendObject;
|
|
|
|
if (gpuSurface->getRenderTargetHandle(&backendObject,
|
|
|
|
SkSurface::kFlushRead_BackendHandleAccess)) {
|
|
|
|
SkString str;
|
|
|
|
str.printf("backendObject=%d", backendObject);
|
|
|
|
paint.setTextSize(16);
|
|
|
|
canvas->drawString(str, 20, 40, paint);
|
|
|
|
}
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso getTextureHandle GrBackendObject BackendHandleAccess
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method SkCanvas* getCanvas()
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
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, Image_Color_Type, Image_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()
|
|
|
|
|
|
|
|
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 ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method void draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method bool readPixels(const SkPixmap& dst, int srcX, int srcY)
|
|
|
|
|
|
|
|
Copies Rect of pixels to dst.
|
|
|
|
|
|
|
|
Source Rect corners are (srcX, srcY) and (this->width(), this->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 Image_Color_Type and Image_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 in x; may be negative ##
|
|
|
|
#Param srcY offset into readable pixels in y; 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
|
|
|
|
|
|
|
|
#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 (this->width(), this->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 Image_Color_Type and Image_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, Image_Color_Type, and Image_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 in x; may be negative ##
|
|
|
|
#Param srcY offset into readable pixels in y; 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
|
|
|
|
|
|
|
|
#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 (this->width(), this->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 Image_Color_Type and Image_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 in x; may be negative ##
|
|
|
|
#Param srcY offset into readable pixels in y; may be negative ##
|
|
|
|
|
|
|
|
#Return true if pixels were copied ##
|
|
|
|
|
|
|
|
#Example
|
2017-12-01 16:49:58 +00:00
|
|
|
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);
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso peekPixels
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method const SkSurfaceProps& props() const
|
|
|
|
|
|
|
|
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" };
|
2017-12-01 16:49:58 +00:00
|
|
|
sk_sp<SkSurface> surf(SkSurface::MakeRasterN32Premul(64, 64));
|
2017-11-27 15:44:06 +00:00
|
|
|
SkDebugf("surf.props(): k%s_SkPixelGeometry\n", names[surf->props().pixelGeometry()]);
|
|
|
|
#StdOut
|
|
|
|
surf.props(): kRGB_H_SkPixelGeometry
|
|
|
|
##
|
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso SkSurfaceProps
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method void prepareForExternalIO()
|
|
|
|
|
|
|
|
To be deprecated.
|
|
|
|
|
|
|
|
#NoExample
|
|
|
|
##
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method void flush()
|
|
|
|
|
|
|
|
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[])
|
|
|
|
|
|
|
|
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 GrBackendSemaphores 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)
|
|
|
|
|
|
|
|
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 ##
|
|
|
|
|
|
|
|
#Example
|
|
|
|
#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
|
|
|
|
##
|
|
|
|
#Platform !fiddle gpu
|
|
|
|
#Height 64
|
2017-12-01 16:49:58 +00:00
|
|
|
SkPaint paint;
|
|
|
|
paint.setTextSize(32);
|
|
|
|
GrContext* context = canvas->getGrContext();
|
|
|
|
if (!context) {
|
|
|
|
canvas->drawString("GPU only!", 20, 40, paint);
|
|
|
|
return;
|
|
|
|
}
|
2017-11-27 15:44:06 +00:00
|
|
|
GrBackendSemaphore semaphore;
|
2017-12-01 16:49:58 +00:00
|
|
|
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
|
|
|
|
context, SkBudgeted::kYes, SkImageInfo::MakeN32Premul(64, 64));
|
2017-11-27 15:44:06 +00:00
|
|
|
surface->flushAndSignalSemaphores(1, &semaphore);
|
|
|
|
sk_sp<SkImage> image = surface->makeImageSnapshot();
|
|
|
|
GrBackendObject backendImage = image->getTextureHandle(false); // unused
|
|
|
|
SkASSERT(backendImage);
|
|
|
|
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);
|
2017-12-01 16:49:58 +00:00
|
|
|
childSurface->draw(canvas, 0, 0, nullptr);
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso flushAndSignalSemaphores GrBackendSemaphore
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method bool characterize(SkSurfaceCharacterization* characterization) const
|
|
|
|
|
|
|
|
Initializes Surface_Characterization that can be used to perform GPU back-end
|
|
|
|
pre-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
|
2017-12-01 16:49:58 +00:00
|
|
|
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);
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso draw() SkSurfaceCharacterization SkDeferredDisplayList
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
#Method void draw(SkDeferredDisplayList* deferredDisplayList)
|
|
|
|
|
|
|
|
Draws deferred display list created using SkDeferredDisplayListRecorder.
|
|
|
|
The draw has no effect if Surface_Characterization stored in deferredDisplayList
|
|
|
|
is not compatible with Surface.
|
|
|
|
|
|
|
|
#Param deferredDisplayList drawing commands ##
|
|
|
|
|
|
|
|
#Example
|
|
|
|
#Height 64
|
|
|
|
#Platform gpu cpu
|
2017-12-01 16:49:58 +00:00
|
|
|
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);
|
2017-11-27 15:44:06 +00:00
|
|
|
##
|
|
|
|
|
|
|
|
#SeeAlso characterize() SkSurfaceCharacterization SkDeferredDisplayList
|
|
|
|
|
|
|
|
#Method ##
|
|
|
|
|
|
|
|
#Class SkSurface ##
|
|
|
|
|
|
|
|
#Topic Surface ##
|