1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkDevice.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,496 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2010 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkDevice_DEFINED 1.14 +#define SkDevice_DEFINED 1.15 + 1.16 +#include "SkRefCnt.h" 1.17 +#include "SkBitmap.h" 1.18 +#include "SkCanvas.h" 1.19 +#include "SkColor.h" 1.20 +#include "SkDeviceProperties.h" 1.21 +#include "SkImageFilter.h" 1.22 + 1.23 +// getDeviceCapabilities() is not called by skia, but this flag keeps it around 1.24 +// for clients that have "override" annotations on their subclass. These overrides 1.25 +// should be deleted. 1.26 +//#define SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES 1.27 + 1.28 +//#define SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 1.29 + 1.30 +class SkClipStack; 1.31 +class SkDraw; 1.32 +struct SkIRect; 1.33 +class SkMatrix; 1.34 +class SkMetaData; 1.35 +class SkRegion; 1.36 + 1.37 +class GrRenderTarget; 1.38 + 1.39 +class SK_API SkBaseDevice : public SkRefCnt { 1.40 +public: 1.41 + SK_DECLARE_INST_COUNT(SkBaseDevice) 1.42 + 1.43 + /** 1.44 + * Construct a new device. 1.45 + */ 1.46 + SkBaseDevice(); 1.47 + 1.48 + /** 1.49 + * Construct a new device. 1.50 + */ 1.51 + SkBaseDevice(const SkDeviceProperties& deviceProperties); 1.52 + 1.53 + virtual ~SkBaseDevice(); 1.54 + 1.55 +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 1.56 + /** 1.57 + * Creates a device that is of the same type as this device (e.g. SW-raster, 1.58 + * GPU, or PDF). The backing store for this device is created automatically 1.59 + * (e.g. offscreen pixels or FBO or whatever is appropriate). 1.60 + * 1.61 + * @param width width of the device to create 1.62 + * @param height height of the device to create 1.63 + * @param isOpaque performance hint, set to true if you know that you will 1.64 + * draw into this device such that all of the pixels will 1.65 + * be opaque. 1.66 + */ 1.67 + SkBaseDevice* createCompatibleDevice(SkBitmap::Config config, 1.68 + int width, int height, 1.69 + bool isOpaque); 1.70 +#endif 1.71 + SkBaseDevice* createCompatibleDevice(const SkImageInfo&); 1.72 + 1.73 + SkMetaData& getMetaData(); 1.74 + 1.75 +#ifdef SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES 1.76 + enum Capabilities { 1.77 + kVector_Capability = 0x1, 1.78 + }; 1.79 + virtual uint32_t getDeviceCapabilities() { return 0; } 1.80 +#endif 1.81 + 1.82 + /** Return the width of the device (in pixels). 1.83 + */ 1.84 + virtual int width() const = 0; 1.85 + /** Return the height of the device (in pixels). 1.86 + */ 1.87 + virtual int height() const = 0; 1.88 + 1.89 + /** Return the image properties of the device. */ 1.90 + virtual const SkDeviceProperties& getDeviceProperties() const { 1.91 + //Currently, all the properties are leaky. 1.92 + return fLeakyProperties; 1.93 + } 1.94 + 1.95 + /** 1.96 + * Return ImageInfo for this device. If the canvas is not backed by pixels 1.97 + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. 1.98 + */ 1.99 + virtual SkImageInfo imageInfo() const; 1.100 + 1.101 + /** 1.102 + * Return the bounds of the device in the coordinate space of the root 1.103 + * canvas. The root device will have its top-left at 0,0, but other devices 1.104 + * such as those associated with saveLayer may have a non-zero origin. 1.105 + */ 1.106 + void getGlobalBounds(SkIRect* bounds) const { 1.107 + SkASSERT(bounds); 1.108 + const SkIPoint& origin = this->getOrigin(); 1.109 + bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height()); 1.110 + } 1.111 + 1.112 + 1.113 + /** Returns true if the device's bitmap's config treats every pixel as 1.114 + implicitly opaque. 1.115 + */ 1.116 + virtual bool isOpaque() const = 0; 1.117 + 1.118 + /** Return the bitmap config of the device's pixels 1.119 + */ 1.120 + virtual SkBitmap::Config config() const = 0; 1.121 + 1.122 + /** Return the bitmap associated with this device. Call this each time you need 1.123 + to access the bitmap, as it notifies the subclass to perform any flushing 1.124 + etc. before you examine the pixels. 1.125 + @param changePixels set to true if the caller plans to change the pixels 1.126 + @return the device's bitmap 1.127 + */ 1.128 + const SkBitmap& accessBitmap(bool changePixels); 1.129 + 1.130 +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG 1.131 + /** 1.132 + * DEPRECATED: This will be made protected once WebKit stops using it. 1.133 + * Instead use Canvas' writePixels method. 1.134 + * 1.135 + * Similar to draw sprite, this method will copy the pixels in bitmap onto 1.136 + * the device, with the top/left corner specified by (x, y). The pixel 1.137 + * values in the device are completely replaced: there is no blending. 1.138 + * 1.139 + * Currently if bitmap is backed by a texture this is a no-op. This may be 1.140 + * relaxed in the future. 1.141 + * 1.142 + * If the bitmap has config kARGB_8888_Config then the config8888 param 1.143 + * will determines how the pixel valuess are intepreted. If the bitmap is 1.144 + * not kARGB_8888_Config then this parameter is ignored. 1.145 + */ 1.146 + virtual void writePixels(const SkBitmap& bitmap, int x, int y, 1.147 + SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888); 1.148 +#endif 1.149 + 1.150 + bool writePixelsDirect(const SkImageInfo&, const void*, size_t rowBytes, int x, int y); 1.151 + 1.152 + void* accessPixels(SkImageInfo* info, size_t* rowBytes); 1.153 + 1.154 + /** 1.155 + * Return the device's associated gpu render target, or NULL. 1.156 + */ 1.157 + virtual GrRenderTarget* accessRenderTarget() = 0; 1.158 + 1.159 + 1.160 + /** 1.161 + * Return the device's origin: its offset in device coordinates from 1.162 + * the default origin in its canvas' matrix/clip 1.163 + */ 1.164 + const SkIPoint& getOrigin() const { return fOrigin; } 1.165 + 1.166 + /** 1.167 + * onAttachToCanvas is invoked whenever a device is installed in a canvas 1.168 + * (i.e., setDevice, saveLayer (for the new device created by the save), 1.169 + * and SkCanvas' SkBaseDevice & SkBitmap -taking ctors). It allows the 1.170 + * devices to prepare for drawing (e.g., locking their pixels, etc.) 1.171 + */ 1.172 + virtual void onAttachToCanvas(SkCanvas*) { 1.173 + SkASSERT(!fAttachedToCanvas); 1.174 + this->lockPixels(); 1.175 +#ifdef SK_DEBUG 1.176 + fAttachedToCanvas = true; 1.177 +#endif 1.178 + }; 1.179 + 1.180 + /** 1.181 + * onDetachFromCanvas notifies a device that it will no longer be drawn to. 1.182 + * It gives the device a chance to clean up (e.g., unlock its pixels). It 1.183 + * is invoked from setDevice (for the displaced device), restore and 1.184 + * possibly from SkCanvas' dtor. 1.185 + */ 1.186 + virtual void onDetachFromCanvas() { 1.187 + SkASSERT(fAttachedToCanvas); 1.188 + this->unlockPixels(); 1.189 +#ifdef SK_DEBUG 1.190 + fAttachedToCanvas = false; 1.191 +#endif 1.192 + }; 1.193 + 1.194 +protected: 1.195 + enum Usage { 1.196 + kGeneral_Usage, 1.197 + kSaveLayer_Usage // <! internal use only 1.198 + }; 1.199 + 1.200 + struct TextFlags { 1.201 + uint32_t fFlags; // SkPaint::getFlags() 1.202 + SkPaint::Hinting fHinting; 1.203 + }; 1.204 + 1.205 + /** 1.206 + * Device may filter the text flags for drawing text here. If it wants to 1.207 + * make a change to the specified values, it should write them into the 1.208 + * textflags parameter (output) and return true. If the paint is fine as 1.209 + * is, then ignore the textflags parameter and return false. 1.210 + * 1.211 + * The baseclass SkBaseDevice filters based on its depth and blitters. 1.212 + */ 1.213 + virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0; 1.214 + 1.215 + /** 1.216 + * 1.217 + * DEPRECATED: This will be removed in a future change. Device subclasses 1.218 + * should use the matrix and clip from the SkDraw passed to draw functions. 1.219 + * 1.220 + * Called with the correct matrix and clip before this device is drawn 1.221 + * to using those settings. If your subclass overrides this, be sure to 1.222 + * call through to the base class as well. 1.223 + * 1.224 + * The clipstack is another view of the clip. It records the actual 1.225 + * geometry that went into building the region. It is present for devices 1.226 + * that want to parse it, but is not required: the region is a complete 1.227 + * picture of the current clip. (i.e. if you regionize all of the geometry 1.228 + * in the clipstack, you will arrive at an equivalent region to the one 1.229 + * passed in). 1.230 + */ 1.231 + virtual void setMatrixClip(const SkMatrix&, const SkRegion&, 1.232 + const SkClipStack&) {}; 1.233 + 1.234 + /** Clears the entire device to the specified color (including alpha). 1.235 + * Ignores the clip. 1.236 + */ 1.237 + virtual void clear(SkColor color) = 0; 1.238 + 1.239 + SK_ATTR_DEPRECATED("use clear() instead") 1.240 + void eraseColor(SkColor eraseColor) { this->clear(eraseColor); } 1.241 + 1.242 + /** These are called inside the per-device-layer loop for each draw call. 1.243 + When these are called, we have already applied any saveLayer operations, 1.244 + and are handling any looping from the paint, and any effects from the 1.245 + DrawFilter. 1.246 + */ 1.247 + virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0; 1.248 + virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, 1.249 + const SkPoint[], const SkPaint& paint) = 0; 1.250 + virtual void drawRect(const SkDraw&, const SkRect& r, 1.251 + const SkPaint& paint) = 0; 1.252 + virtual void drawOval(const SkDraw&, const SkRect& oval, 1.253 + const SkPaint& paint) = 0; 1.254 + virtual void drawRRect(const SkDraw&, const SkRRect& rr, 1.255 + const SkPaint& paint) = 0; 1.256 + 1.257 + // Default impl calls drawPath() 1.258 + virtual void drawDRRect(const SkDraw&, const SkRRect& outer, 1.259 + const SkRRect& inner, const SkPaint&); 1.260 + 1.261 + /** 1.262 + * If pathIsMutable, then the implementation is allowed to cast path to a 1.263 + * non-const pointer and modify it in place (as an optimization). Canvas 1.264 + * may do this to implement helpers such as drawOval, by placing a temp 1.265 + * path on the stack to hold the representation of the oval. 1.266 + * 1.267 + * If prePathMatrix is not null, it should logically be applied before any 1.268 + * stroking or other effects. If there are no effects on the paint that 1.269 + * affect the geometry/rasterization, then the pre matrix can just be 1.270 + * pre-concated with the current matrix. 1.271 + */ 1.272 + virtual void drawPath(const SkDraw&, const SkPath& path, 1.273 + const SkPaint& paint, 1.274 + const SkMatrix* prePathMatrix = NULL, 1.275 + bool pathIsMutable = false) = 0; 1.276 + virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, 1.277 + const SkMatrix& matrix, const SkPaint& paint) = 0; 1.278 + virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, 1.279 + int x, int y, const SkPaint& paint) = 0; 1.280 + 1.281 + /** 1.282 + * The default impl. will create a bitmap-shader from the bitmap, 1.283 + * and call drawRect with it. 1.284 + */ 1.285 + virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, 1.286 + const SkRect* srcOrNull, const SkRect& dst, 1.287 + const SkPaint& paint, 1.288 + SkCanvas::DrawBitmapRectFlags flags) = 0; 1.289 + 1.290 + /** 1.291 + * Does not handle text decoration. 1.292 + * Decorations (underline and stike-thru) will be handled by SkCanvas. 1.293 + */ 1.294 + virtual void drawText(const SkDraw&, const void* text, size_t len, 1.295 + SkScalar x, SkScalar y, const SkPaint& paint) = 0; 1.296 + virtual void drawPosText(const SkDraw&, const void* text, size_t len, 1.297 + const SkScalar pos[], SkScalar constY, 1.298 + int scalarsPerPos, const SkPaint& paint) = 0; 1.299 + virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, 1.300 + const SkPath& path, const SkMatrix* matrix, 1.301 + const SkPaint& paint) = 0; 1.302 + virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, 1.303 + const SkPoint verts[], const SkPoint texs[], 1.304 + const SkColor colors[], SkXfermode* xmode, 1.305 + const uint16_t indices[], int indexCount, 1.306 + const SkPaint& paint) = 0; 1.307 + /** The SkDevice passed will be an SkDevice which was returned by a call to 1.308 + onCreateDevice on this device with kSaveLayer_Usage. 1.309 + */ 1.310 + virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, 1.311 + const SkPaint&) = 0; 1.312 + 1.313 + /** 1.314 + * On success (returns true), copy the device pixels into the bitmap. 1.315 + * On failure, the bitmap parameter is left unchanged and false is 1.316 + * returned. 1.317 + * 1.318 + * The device's pixels are converted to the bitmap's config. The only 1.319 + * supported config is kARGB_8888_Config, though this is likely to be 1.320 + * relaxed in the future. The meaning of config kARGB_8888_Config is 1.321 + * modified by the enum param config8888. The default value interprets 1.322 + * kARGB_8888_Config as SkPMColor 1.323 + * 1.324 + * If the bitmap has pixels already allocated, the device pixels will be 1.325 + * written there. If not, bitmap->allocPixels() will be called 1.326 + * automatically. If the bitmap is backed by a texture readPixels will 1.327 + * fail. 1.328 + * 1.329 + * The actual pixels written is the intersection of the device's bounds, 1.330 + * and the rectangle formed by the bitmap's width,height and the specified 1.331 + * x,y. If bitmap pixels extend outside of that intersection, they will not 1.332 + * be modified. 1.333 + * 1.334 + * Other failure conditions: 1.335 + * * If the device is not a raster device (e.g. PDF) then readPixels will 1.336 + * fail. 1.337 + * * If bitmap is texture-backed then readPixels will fail. (This may be 1.338 + * relaxed in the future.) 1.339 + */ 1.340 + bool readPixels(SkBitmap* bitmap, 1.341 + int x, int y, 1.342 + SkCanvas::Config8888 config8888); 1.343 + 1.344 + /////////////////////////////////////////////////////////////////////////// 1.345 + 1.346 + /** Update as needed the pixel value in the bitmap, so that the caller can 1.347 + access the pixels directly. 1.348 + @return The device contents as a bitmap 1.349 + */ 1.350 + virtual const SkBitmap& onAccessBitmap() = 0; 1.351 + 1.352 + /** Called when this device is installed into a Canvas. Balanced by a call 1.353 + to unlockPixels() when the device is removed from a Canvas. 1.354 + */ 1.355 + virtual void lockPixels() = 0; 1.356 + virtual void unlockPixels() = 0; 1.357 + 1.358 + /** 1.359 + * Returns true if the device allows processing of this imagefilter. If 1.360 + * false is returned, then the filter is ignored. This may happen for 1.361 + * some subclasses that do not support pixel manipulations after drawing 1.362 + * has occurred (e.g. printing). The default implementation returns true. 1.363 + */ 1.364 + virtual bool allowImageFilter(const SkImageFilter*) = 0; 1.365 + 1.366 + /** 1.367 + * Override and return true for filters that the device can handle 1.368 + * intrinsically. Doing so means that SkCanvas will pass-through this 1.369 + * filter to drawSprite and drawDevice (and potentially filterImage). 1.370 + * Returning false means the SkCanvas will have apply the filter itself, 1.371 + * and just pass the resulting image to the device. 1.372 + */ 1.373 + virtual bool canHandleImageFilter(const SkImageFilter*) = 0; 1.374 + 1.375 + /** 1.376 + * Related (but not required) to canHandleImageFilter, this method returns 1.377 + * true if the device could apply the filter to the src bitmap and return 1.378 + * the result (and updates offset as needed). 1.379 + * If the device does not recognize or support this filter, 1.380 + * it just returns false and leaves result and offset unchanged. 1.381 + */ 1.382 + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, 1.383 + const SkImageFilter::Context& ctx, 1.384 + SkBitmap* result, SkIPoint* offset) = 0; 1.385 + 1.386 + // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if 1.387 + // either is identical to kNative_Premul_Config8888. Otherwise, -1. 1.388 + static const SkCanvas::Config8888 kPMColorAlias; 1.389 + 1.390 +protected: 1.391 + // default impl returns NULL 1.392 + virtual SkSurface* newSurface(const SkImageInfo&); 1.393 + 1.394 + // default impl returns NULL 1.395 + virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes); 1.396 + 1.397 + /** 1.398 + * Implements readPixels API. The caller will ensure that: 1.399 + * 1. bitmap has pixel config kARGB_8888_Config. 1.400 + * 2. bitmap has pixels. 1.401 + * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is 1.402 + * contained in the device bounds. 1.403 + */ 1.404 + virtual bool onReadPixels(const SkBitmap& bitmap, 1.405 + int x, int y, 1.406 + SkCanvas::Config8888 config8888); 1.407 + 1.408 + /** 1.409 + * The caller is responsible for "pre-clipping" the src. The impl can assume that the src 1.410 + * image at the specified x,y offset will fit within the device's bounds. 1.411 + * 1.412 + * This is explicitly asserted in writePixelsDirect(), the public way to call this. 1.413 + */ 1.414 + virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y); 1.415 + 1.416 + /** 1.417 + * Default impl returns NULL. 1.418 + */ 1.419 + virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes); 1.420 + 1.421 + /** 1.422 + * Leaky properties are those which the device should be applying but it isn't. 1.423 + * These properties will be applied by the draw, when and as it can. 1.424 + * If the device does handle a property, that property should be set to the identity value 1.425 + * for that property, effectively making it non-leaky. 1.426 + */ 1.427 + SkDeviceProperties fLeakyProperties; 1.428 + 1.429 + /** 1.430 + * PRIVATE / EXPERIMENTAL -- do not call 1.431 + * Construct an acceleration object and attach it to 'picture' 1.432 + */ 1.433 + virtual void EXPERIMENTAL_optimize(SkPicture* picture); 1.434 + 1.435 + /** 1.436 + * PRIVATE / EXPERIMENTAL -- do not call 1.437 + * This entry point gives the backend an opportunity to take over the rendering 1.438 + * of 'picture'. If optimization data is available (due to an earlier 1.439 + * 'optimize' call) this entry point should make use of it and return true 1.440 + * if all rendering has been done. If false is returned, SkCanvas will 1.441 + * perform its own rendering pass. It is acceptable for the backend 1.442 + * to perform some device-specific warm up tasks and then let SkCanvas 1.443 + * perform the main rendering loop (by return false from here). 1.444 + */ 1.445 + virtual bool EXPERIMENTAL_drawPicture(const SkPicture& picture); 1.446 + 1.447 +private: 1.448 + friend class SkCanvas; 1.449 + friend struct DeviceCM; //for setMatrixClip 1.450 + friend class SkDraw; 1.451 + friend class SkDrawIter; 1.452 + friend class SkDeviceFilteredPaint; 1.453 + friend class SkDeviceImageFilterProxy; 1.454 + friend class SkDeferredDevice; // for newSurface 1.455 + 1.456 + friend class SkSurface_Raster; 1.457 + 1.458 + // used to change the backend's pixels (and possibly config/rowbytes) 1.459 + // but cannot change the width/height, so there should be no change to 1.460 + // any clip information. 1.461 + // TODO: move to SkBitmapDevice 1.462 + virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0; 1.463 + 1.464 + // just called by SkCanvas when built as a layer 1.465 + void setOrigin(int x, int y) { fOrigin.set(x, y); } 1.466 + // just called by SkCanvas for saveLayer 1.467 + SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&); 1.468 + 1.469 +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 1.470 + /** 1.471 + * Justs exists during the period where clients still "override" this 1.472 + * signature. They are supported by our base-impl calling this old 1.473 + * signature from the new one (using ImageInfo). 1.474 + */ 1.475 + virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, 1.476 + int width, int height, 1.477 + bool isOpaque, Usage) { 1.478 + return NULL; 1.479 + } 1.480 +#endif 1.481 + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) { 1.482 + return NULL; 1.483 + } 1.484 + 1.485 + /** Causes any deferred drawing to the device to be completed. 1.486 + */ 1.487 + virtual void flush() = 0; 1.488 + 1.489 + SkIPoint fOrigin; 1.490 + SkMetaData* fMetaData; 1.491 + 1.492 +#ifdef SK_DEBUG 1.493 + bool fAttachedToCanvas; 1.494 +#endif 1.495 + 1.496 + typedef SkRefCnt INHERITED; 1.497 +}; 1.498 + 1.499 +#endif