1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/utils/SkPictureUtils.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,237 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBitmapDevice.h" 1.12 +#include "SkCanvas.h" 1.13 +#include "SkData.h" 1.14 +#include "SkNoSaveLayerCanvas.h" 1.15 +#include "SkPictureUtils.h" 1.16 +#include "SkPixelRef.h" 1.17 +#include "SkRRect.h" 1.18 +#include "SkShader.h" 1.19 + 1.20 +class PixelRefSet { 1.21 +public: 1.22 + PixelRefSet(SkTDArray<SkPixelRef*>* array) : fArray(array) {} 1.23 + 1.24 + // This does a linear search on existing pixelrefs, so if this list gets big 1.25 + // we should use a more complex sorted/hashy thing. 1.26 + // 1.27 + void add(SkPixelRef* pr) { 1.28 + uint32_t genID = pr->getGenerationID(); 1.29 + if (fGenID.find(genID) < 0) { 1.30 + *fArray->append() = pr; 1.31 + *fGenID.append() = genID; 1.32 +// SkDebugf("--- adding [%d] %x %d\n", fArray->count() - 1, pr, genID); 1.33 + } else { 1.34 +// SkDebugf("--- already have %x %d\n", pr, genID); 1.35 + } 1.36 + } 1.37 + 1.38 +private: 1.39 + SkTDArray<SkPixelRef*>* fArray; 1.40 + SkTDArray<uint32_t> fGenID; 1.41 +}; 1.42 + 1.43 +static void not_supported() { 1.44 + SkDEBUGFAIL("this method should never be called"); 1.45 +} 1.46 + 1.47 +static void nothing_to_do() {} 1.48 + 1.49 +/** 1.50 + * This device will route all bitmaps (primitives and in shaders) to its PRSet. 1.51 + * It should never actually draw anything, so there need not be any pixels 1.52 + * behind its device. 1.53 + */ 1.54 +class GatherPixelRefDevice : public SkBaseDevice { 1.55 +public: 1.56 + SK_DECLARE_INST_COUNT(GatherPixelRefDevice) 1.57 + 1.58 + GatherPixelRefDevice(int width, int height, PixelRefSet* prset) { 1.59 + fSize.set(width, height); 1.60 + fEmptyBitmap.setConfig(SkImageInfo::MakeUnknown(width, height)); 1.61 + fPRSet = prset; 1.62 + } 1.63 + 1.64 + virtual int width() const SK_OVERRIDE { return fSize.width(); } 1.65 + virtual int height() const SK_OVERRIDE { return fSize.height(); } 1.66 + virtual bool isOpaque() const SK_OVERRIDE { return false; } 1.67 + virtual SkBitmap::Config config() const SK_OVERRIDE { 1.68 + return SkBitmap::kNo_Config; 1.69 + } 1.70 + virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } 1.71 + virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { 1.72 + return false; 1.73 + } 1.74 + // TODO: allow this call to return failure, or move to SkBitmapDevice only. 1.75 + virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE { 1.76 + return fEmptyBitmap; 1.77 + } 1.78 + virtual void lockPixels() SK_OVERRIDE { nothing_to_do(); } 1.79 + virtual void unlockPixels() SK_OVERRIDE { nothing_to_do(); } 1.80 + virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } 1.81 + virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } 1.82 + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, 1.83 + SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { 1.84 + return false; 1.85 + } 1.86 + 1.87 + virtual void clear(SkColor color) SK_OVERRIDE { 1.88 + nothing_to_do(); 1.89 + } 1.90 + 1.91 +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG 1.92 + virtual void writePixels(const SkBitmap& bitmap, int x, int y, 1.93 + SkCanvas::Config8888 config8888) SK_OVERRIDE { 1.94 + not_supported(); 1.95 + } 1.96 +#endif 1.97 + 1.98 + virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE { 1.99 + this->addBitmapFromPaint(paint); 1.100 + } 1.101 + virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, 1.102 + const SkPoint[], const SkPaint& paint) SK_OVERRIDE { 1.103 + this->addBitmapFromPaint(paint); 1.104 + } 1.105 + virtual void drawRect(const SkDraw&, const SkRect&, 1.106 + const SkPaint& paint) SK_OVERRIDE { 1.107 + this->addBitmapFromPaint(paint); 1.108 + } 1.109 + virtual void drawRRect(const SkDraw&, const SkRRect&, 1.110 + const SkPaint& paint) SK_OVERRIDE { 1.111 + this->addBitmapFromPaint(paint); 1.112 + } 1.113 + virtual void drawOval(const SkDraw&, const SkRect&, 1.114 + const SkPaint& paint) SK_OVERRIDE { 1.115 + this->addBitmapFromPaint(paint); 1.116 + } 1.117 + virtual void drawPath(const SkDraw&, const SkPath& path, 1.118 + const SkPaint& paint, const SkMatrix* prePathMatrix, 1.119 + bool pathIsMutable) SK_OVERRIDE { 1.120 + this->addBitmapFromPaint(paint); 1.121 + } 1.122 + virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, 1.123 + const SkMatrix&, const SkPaint& paint) SK_OVERRIDE { 1.124 + this->addBitmap(bitmap); 1.125 + if (SkBitmap::kA8_Config == bitmap.config()) { 1.126 + this->addBitmapFromPaint(paint); 1.127 + } 1.128 + } 1.129 + virtual void drawBitmapRect(const SkDraw&, const SkBitmap& bitmap, 1.130 + const SkRect* srcOrNull, const SkRect& dst, 1.131 + const SkPaint& paint, 1.132 + SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE { 1.133 + this->addBitmap(bitmap); 1.134 + if (SkBitmap::kA8_Config == bitmap.config()) { 1.135 + this->addBitmapFromPaint(paint); 1.136 + } 1.137 + } 1.138 + virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, 1.139 + int x, int y, const SkPaint& paint) SK_OVERRIDE { 1.140 + this->addBitmap(bitmap); 1.141 + } 1.142 + virtual void drawText(const SkDraw&, const void* text, size_t len, 1.143 + SkScalar x, SkScalar y, 1.144 + const SkPaint& paint) SK_OVERRIDE { 1.145 + this->addBitmapFromPaint(paint); 1.146 + } 1.147 + virtual void drawPosText(const SkDraw&, const void* text, size_t len, 1.148 + const SkScalar pos[], SkScalar constY, 1.149 + int, const SkPaint& paint) SK_OVERRIDE { 1.150 + this->addBitmapFromPaint(paint); 1.151 + } 1.152 + virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, 1.153 + const SkPath& path, const SkMatrix* matrix, 1.154 + const SkPaint& paint) SK_OVERRIDE { 1.155 + this->addBitmapFromPaint(paint); 1.156 + } 1.157 + virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, 1.158 + const SkPoint verts[], const SkPoint texs[], 1.159 + const SkColor colors[], SkXfermode* xmode, 1.160 + const uint16_t indices[], int indexCount, 1.161 + const SkPaint& paint) SK_OVERRIDE { 1.162 + this->addBitmapFromPaint(paint); 1.163 + } 1.164 + virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 1.165 + const SkPaint&) SK_OVERRIDE { 1.166 + nothing_to_do(); 1.167 + } 1.168 + 1.169 +protected: 1.170 + virtual bool onReadPixels(const SkBitmap& bitmap, 1.171 + int x, int y, 1.172 + SkCanvas::Config8888 config8888) SK_OVERRIDE { 1.173 + not_supported(); 1.174 + return false; 1.175 + } 1.176 + 1.177 + virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE { 1.178 + not_supported(); 1.179 + } 1.180 + virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE { 1.181 + // we expect to only get called via savelayer, in which case it is fine. 1.182 + SkASSERT(kSaveLayer_Usage == usage); 1.183 + return SkNEW_ARGS(GatherPixelRefDevice, (info.width(), info.height(), fPRSet)); 1.184 + } 1.185 + virtual void flush() SK_OVERRIDE {} 1.186 + 1.187 +private: 1.188 + PixelRefSet* fPRSet; 1.189 + SkBitmap fEmptyBitmap; // legacy -- need to remove the need for this guy 1.190 + SkISize fSize; 1.191 + 1.192 + void addBitmap(const SkBitmap& bm) { 1.193 + fPRSet->add(bm.pixelRef()); 1.194 + } 1.195 + 1.196 + void addBitmapFromPaint(const SkPaint& paint) { 1.197 + SkShader* shader = paint.getShader(); 1.198 + if (shader) { 1.199 + SkBitmap bm; 1.200 + // Check whether the shader is a gradient in order to short-circuit 1.201 + // call to asABitmap to prevent generation of bitmaps from 1.202 + // gradient shaders, which implement asABitmap. 1.203 + if (SkShader::kNone_GradientType == shader->asAGradient(NULL) && 1.204 + shader->asABitmap(&bm, NULL, NULL)) { 1.205 + fPRSet->add(bm.pixelRef()); 1.206 + } 1.207 + } 1.208 + } 1.209 + 1.210 + typedef SkBaseDevice INHERITED; 1.211 +}; 1.212 + 1.213 +SkData* SkPictureUtils::GatherPixelRefs(SkPicture* pict, const SkRect& area) { 1.214 + if (NULL == pict) { 1.215 + return NULL; 1.216 + } 1.217 + 1.218 + // this test also handles if either area or pict's width/height are empty 1.219 + if (!SkRect::Intersects(area, 1.220 + SkRect::MakeWH(SkIntToScalar(pict->width()), 1.221 + SkIntToScalar(pict->height())))) { 1.222 + return NULL; 1.223 + } 1.224 + 1.225 + SkTDArray<SkPixelRef*> array; 1.226 + PixelRefSet prset(&array); 1.227 + 1.228 + GatherPixelRefDevice device(pict->width(), pict->height(), &prset); 1.229 + SkNoSaveLayerCanvas canvas(&device); 1.230 + 1.231 + canvas.clipRect(area, SkRegion::kIntersect_Op, false); 1.232 + canvas.drawPicture(*pict); 1.233 + 1.234 + SkData* data = NULL; 1.235 + int count = array.count(); 1.236 + if (count > 0) { 1.237 + data = SkData::NewFromMalloc(array.detach(), count * sizeof(SkPixelRef*)); 1.238 + } 1.239 + return data; 1.240 +}