#if SK_SUPPORT_GPU
+#define ASSERT_SINGLE_OWNER \
+ SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->debugSingleOwner());)
+
enum { kDefaultImageFilterCacheSize = 32 * 1024 * 1024 };
#if 0
bool SkGpuDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int x, int y) {
+ ASSERT_SINGLE_OWNER
DO_DEFERRED_CLEAR();
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes,
int x, int y) {
+ ASSERT_SINGLE_OWNER
// TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels
GrPixelConfig config = SkImageInfo2GrPixelConfig(info);
if (kUnknown_GrPixelConfig == config) {
}
const SkBitmap& SkGpuDevice::onAccessBitmap() {
+ ASSERT_SINGLE_OWNER
DO_DEFERRED_CLEAR();
return fLegacyBitmap;
}
bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) {
+ ASSERT_SINGLE_OWNER
DO_DEFERRED_CLEAR();
// For compatibility with clients the know we're backed w/ a bitmap, and want to inspect its
// genID. When we can hide/remove that fact, we can eliminate this call to notify.
}
void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
+ ASSERT_SINGLE_OWNER
INHERITED::onAttachToCanvas(canvas);
// Canvas promises that this ptr is valid until onDetachFromCanvas is called
}
void SkGpuDevice::onDetachFromCanvas() {
+ ASSERT_SINGLE_OWNER
INHERITED::onDetachFromCanvas();
fClip.reset();
fClipStack.reset(nullptr);
// call this every draw call, to ensure that the context reflects our state,
// and not the state from some other canvas/device
void SkGpuDevice::prepareDraw(const SkDraw& draw) {
+ ASSERT_SINGLE_OWNER
SkASSERT(fClipStack.get());
SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
}
GrRenderTarget* SkGpuDevice::accessRenderTarget() {
+ ASSERT_SINGLE_OWNER
DO_DEFERRED_CLEAR();
return fRenderTarget;
}
void SkGpuDevice::clearAll() {
+ ASSERT_SINGLE_OWNER
GrColor color = 0;
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "clearAll", fContext);
SkIRect rect = SkIRect::MakeWH(this->width(), this->height());
}
void SkGpuDevice::replaceRenderTarget(bool shouldRetainContent) {
+ ASSERT_SINGLE_OWNER
// Caller must have accessed the render target, because it knows the rt must be replaced.
SkASSERT(!fNeedClear);
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPaint", fContext);
void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
size_t count, const SkPoint pts[], const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext);
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect,
const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext);
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
const SkRRect& inner, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDRRect", fContext);
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
/////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawOval", fContext);
CHECK_FOR_ANNOTATION(paint);
CHECK_SHOULD_DRAW(draw);
void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable) {
+ ASSERT_SINGLE_OWNER
if (!origSrcPath.isInverseFillType() && !paint.getPathEffect() && !prePathMatrix) {
bool isClosed;
SkRect rect;
int maxTileSize,
int* tileSize,
SkIRect* clippedSubset) const {
+ ASSERT_SINGLE_OWNER
// if it's larger than the max tile size, then we have no choice but tiling.
if (imageRect.width() > maxTileSize || imageRect.height() > maxTileSize) {
determine_clipped_src_rect(fRenderTarget, fClip, viewMatrix, imageRect.size(),
int maxTileSize,
int* tileSize,
SkIRect* clippedSrcRect) const {
+ ASSERT_SINGLE_OWNER
// if bitmap is explictly texture backed then just use the texture
if (bitmap.getTexture()) {
return false;
bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr,
SkCanvas::SrcRectConstraint constraint, SkFilterQuality quality,
const SkMatrix& viewMatrix) const {
+ ASSERT_SINGLE_OWNER
// if image is explictly texture backed then just use the texture
if (as_IB(image)->peekTexture()) {
return false;
const SkBitmap& bitmap,
const SkMatrix& m,
const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
CHECK_SHOULD_DRAW(origDraw);
SkMatrix viewMatrix;
viewMatrix.setConcat(*origDraw.fMatrix, m);
SkCanvas::SrcRectConstraint constraint,
int tileSize,
bool bicubic) {
+ ASSERT_SINGLE_OWNER
// The following pixel lock is technically redundant, but it is desirable
// to lock outside of the tile loop to prevent redecoding the whole image
// at each tile in cases where 'bitmap' holds an SkDiscardablePixelRef that
const SkImageFilter* filter,
const SkImageFilter::Context& ctx,
SkBitmap* result, SkIPoint* offset) {
+ ASSERT_SINGLE_OWNER
SkASSERT(filter);
SkImageFilter::DeviceProxy proxy(this);
void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
int left, int top, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
// drawSprite is defined to be in device coords.
CHECK_SHOULD_DRAW(draw);
void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
const SkRect* src, const SkRect& origDst,
const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
+ ASSERT_SINGLE_OWNER
if (bitmap.getTexture()) {
CHECK_SHOULD_DRAW(draw);
GrBitmapTextureAdjuster adjuster(&bitmap);
void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
int x, int y, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
// clear of the source device must occur before CHECK_SHOULD_DRAW
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext);
SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
}
bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
+ ASSERT_SINGLE_OWNER
return filter->canFilterImageGPU();
}
bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src,
const SkImageFilter::Context& ctx,
SkBitmap* result, SkIPoint* offset) {
+ ASSERT_SINGLE_OWNER
// want explicitly our impl, so guard against a subclass of us overriding it
if (!this->SkGpuDevice::canHandleImageFilter(filter)) {
return false;
void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
SkMatrix viewMatrix = *draw.fMatrix;
viewMatrix.preTranslate(x, y);
if (as_IB(image)->peekTexture()) {
void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
const SkRect& dst, const SkPaint& paint,
SkCanvas::SrcRectConstraint constraint) {
+ ASSERT_SINGLE_OWNER
if (as_IB(image)->peekTexture()) {
CHECK_SHOULD_DRAW(draw);
GrImageTextureAdjuster adjuster(as_IB(image));
void SkGpuDevice::drawImageNine(const SkDraw& draw, const SkImage* image,
const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
if (as_IB(image)->peekTexture()) {
GrImageTextureAdjuster adjuster(as_IB(image));
this->drawProducerNine(draw, &adjuster, center, dst, paint);
void SkGpuDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
const SkRect& dst, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
if (bitmap.getTexture()) {
GrBitmapTextureAdjuster adjuster(&bitmap);
this->drawProducerNine(draw, &adjuster, center, dst, paint);
SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext);
void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
const SkRect texRect[], const SkColor colors[], int count,
SkXfermode::Mode mode, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
if (paint.isAntiAlias()) {
this->INHERITED::drawAtlas(draw, atlas, xform, texRect, colors, count, mode, paint);
return;
void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
size_t byteLength, SkScalar x, SkScalar y,
const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
CHECK_SHOULD_DRAW(draw);
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext);
void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPosText", fContext);
CHECK_SHOULD_DRAW(draw);
void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
const SkPaint& paint, SkDrawFilter* drawFilter) {
+ ASSERT_SINGLE_OWNER
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawTextBlob", fContext);
CHECK_SHOULD_DRAW(draw);
}
void SkGpuDevice::flush() {
+ ASSERT_SINGLE_OWNER
DO_DEFERRED_CLEAR();
fRenderTarget->prepareForExternalIO();
///////////////////////////////////////////////////////////////////////////////
SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint*) {
+ ASSERT_SINGLE_OWNER
GrSurfaceDesc desc;
desc.fConfig = fRenderTarget->config();
desc.fFlags = kRenderTarget_GrSurfaceFlag;
}
SkSurface* SkGpuDevice::newSurface(const SkImageInfo& info, const SkSurfaceProps& props) {
+ ASSERT_SINGLE_OWNER
// TODO: Change the signature of newSurface to take a budgeted parameter.
static const SkSurface::Budgeted kBudgeted = SkSurface::kNo_Budgeted;
return SkSurface::NewRenderTarget(fContext, kBudgeted, info, fRenderTarget->desc().fSampleCnt,
bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture* mainPicture,
const SkMatrix* matrix, const SkPaint* paint) {
+ ASSERT_SINGLE_OWNER
#ifndef SK_IGNORE_GPU_LAYER_HOISTING
// todo: should handle this natively
if (paint) {
}
SkImageFilter::Cache* SkGpuDevice::getImageFilterCache() {
+ ASSERT_SINGLE_OWNER
// We always return a transient cache, so it is freed after each
// filter traversal.
return SkGpuDevice::NewImageFilterCache();