-
/*
* Copyright 2010 The Android Open Source Project
*
* found in the LICENSE file.
*/
-
#ifndef SkDevice_DEFINED
#define SkDevice_DEFINED
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColor.h"
-#include "SkDeviceProperties.h"
+#include "SkImageFilter.h"
class SkClipStack;
class SkDraw;
class SkMatrix;
class SkMetaData;
class SkRegion;
-
+struct SkDeviceProperties;
class GrRenderTarget;
class SK_API SkBaseDevice : public SkRefCnt {
* Construct a new device.
*/
SkBaseDevice();
-
- /**
- * Construct a new device.
- */
- SkBaseDevice(const SkDeviceProperties& deviceProperties);
-
virtual ~SkBaseDevice();
- /**
- * Creates a device that is of the same type as this device (e.g. SW-raster,
- * GPU, or PDF). The backing store for this device is created automatically
- * (e.g. offscreen pixels or FBO or whatever is appropriate).
- *
- * @param width width of the device to create
- * @param height height of the device to create
- * @param isOpaque performance hint, set to true if you know that you will
- * draw into this device such that all of the pixels will
- * be opaque.
- */
- SkBaseDevice* createCompatibleDevice(SkBitmap::Config config,
- int width, int height,
- bool isOpaque);
+ SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
SkMetaData& getMetaData();
- enum Capabilities {
- kGL_Capability = 0x1, //!< mask indicating GL support
- kVector_Capability = 0x2, //!< mask indicating a vector representation
- kAll_Capabilities = 0x3
- };
- virtual uint32_t getDeviceCapabilities() = 0;
-
- /** Return the width of the device (in pixels).
- */
- virtual int width() const = 0;
- /** Return the height of the device (in pixels).
- */
- virtual int height() const = 0;
-
- /** Return the image properties of the device. */
- virtual const SkDeviceProperties& getDeviceProperties() const {
- //Currently, all the properties are leaky.
- return fLeakyProperties;
- }
+ /**
+ * Return ImageInfo for this device. If the canvas is not backed by pixels
+ * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType.
+ */
+ virtual SkImageInfo imageInfo() const;
/**
* Return the bounds of the device in the coordinate space of the root
bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
}
+ int width() const {
+ return this->imageInfo().width();
+ }
- /** Returns true if the device's bitmap's config treats every pixel as
- implicitly opaque.
- */
- virtual bool isOpaque() const = 0;
+ int height() const {
+ return this->imageInfo().height();
+ }
- /** Return the bitmap config of the device's pixels
- */
- SK_ATTR_DEPRECATED("want to hide configness of the device -- don't use")
- virtual SkBitmap::Config config() const = 0;
+ bool isOpaque() const {
+ return this->imageInfo().isOpaque();
+ }
/** Return the bitmap associated with this device. Call this each time you need
to access the bitmap, as it notifies the subclass to perform any flushing
*/
const SkBitmap& accessBitmap(bool changePixels);
- /**
- * DEPRECATED: This will be made protected once WebKit stops using it.
- * Instead use Canvas' writePixels method.
- *
- * Similar to draw sprite, this method will copy the pixels in bitmap onto
- * the device, with the top/left corner specified by (x, y). The pixel
- * values in the device are completely replaced: there is no blending.
- *
- * Currently if bitmap is backed by a texture this is a no-op. This may be
- * relaxed in the future.
- *
- * If the bitmap has config kARGB_8888_Config then the config8888 param
- * will determines how the pixel valuess are intepreted. If the bitmap is
- * not kARGB_8888_Config then this parameter is ignored.
- */
- virtual void writePixels(const SkBitmap& bitmap, int x, int y,
- SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0;
+ bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
+
+ void* accessPixels(SkImageInfo* info, size_t* rowBytes);
/**
* Return the device's associated gpu render target, or NULL.
*/
- virtual GrRenderTarget* accessRenderTarget() = 0;
+ virtual GrRenderTarget* accessRenderTarget() { return NULL; }
/**
};
struct TextFlags {
- uint32_t fFlags; // SkPaint::getFlags()
- SkPaint::Hinting fHinting;
+ uint32_t fFlags; // SkPaint::getFlags()
};
/**
* make a change to the specified values, it should write them into the
* textflags parameter (output) and return true. If the paint is fine as
* is, then ignore the textflags parameter and return false.
- *
- * The baseclass SkBaseDevice filters based on its depth and blitters.
*/
- virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
+ virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) { return false; }
/**
*
virtual void drawRRect(const SkDraw&, const SkRRect& rr,
const SkPaint& paint) = 0;
+ // Default impl calls drawPath()
+ virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
+ const SkRRect& inner, const SkPaint&);
+
/**
* If pathIsMutable, then the implementation is allowed to cast path to a
* non-const pointer and modify it in place (as an optimization). Canvas
const SkColor colors[], SkXfermode* xmode,
const uint16_t indices[], int indexCount,
const SkPaint& paint) = 0;
+ // default implementation unrolls the blob runs.
+ virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+ const SkPaint& paint);
+ // default implementation calls drawVertices
+ virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
/** The SkDevice passed will be an SkDevice which was returned by a call to
- onCreateCompatibleDevice on this device with kSaveLayer_Usage.
+ onCreateDevice on this device with kSaveLayer_Usage.
*/
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
const SkPaint&) = 0;
- /**
- * On success (returns true), copy the device pixels into the bitmap.
- * On failure, the bitmap parameter is left unchanged and false is
- * returned.
- *
- * The device's pixels are converted to the bitmap's config. The only
- * supported config is kARGB_8888_Config, though this is likely to be
- * relaxed in the future. The meaning of config kARGB_8888_Config is
- * modified by the enum param config8888. The default value interprets
- * kARGB_8888_Config as SkPMColor
- *
- * If the bitmap has pixels already allocated, the device pixels will be
- * written there. If not, bitmap->allocPixels() will be called
- * automatically. If the bitmap is backed by a texture readPixels will
- * fail.
- *
- * The actual pixels written is the intersection of the device's bounds,
- * and the rectangle formed by the bitmap's width,height and the specified
- * x,y. If bitmap pixels extend outside of that intersection, they will not
- * be modified.
- *
- * Other failure conditions:
- * * If the device is not a raster device (e.g. PDF) then readPixels will
- * fail.
- * * If bitmap is texture-backed then readPixels will fail. (This may be
- * relaxed in the future.)
- */
- bool readPixels(SkBitmap* bitmap,
- int x, int y,
- SkCanvas::Config8888 config8888);
+ bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
///////////////////////////////////////////////////////////////////////////
*/
virtual const SkBitmap& onAccessBitmap() = 0;
- /**
- * Implements readPixels API. The caller will ensure that:
- * 1. bitmap has pixel config kARGB_8888_Config.
- * 2. bitmap has pixels.
- * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
- * contained in the device bounds.
- */
- virtual bool onReadPixels(const SkBitmap& bitmap,
- int x, int y,
- SkCanvas::Config8888 config8888) = 0;
-
/** Called when this device is installed into a Canvas. Balanced by a call
to unlockPixels() when the device is removed from a Canvas.
*/
- virtual void lockPixels() = 0;
- virtual void unlockPixels() = 0;
+ virtual void lockPixels() {}
+ virtual void unlockPixels() {}
/**
* Returns true if the device allows processing of this imagefilter. If
* some subclasses that do not support pixel manipulations after drawing
* has occurred (e.g. printing). The default implementation returns true.
*/
- virtual bool allowImageFilter(SkImageFilter*) = 0;
+ virtual bool allowImageFilter(const SkImageFilter*) { return true; }
/**
* Override and return true for filters that the device can handle
* Returning false means the SkCanvas will have apply the filter itself,
* and just pass the resulting image to the device.
*/
- virtual bool canHandleImageFilter(SkImageFilter*) = 0;
+ virtual bool canHandleImageFilter(const SkImageFilter*) { return false; }
/**
* Related (but not required) to canHandleImageFilter, this method returns
* If the device does not recognize or support this filter,
* it just returns false and leaves result and offset unchanged.
*/
- virtual bool filterImage(SkImageFilter*, const SkBitmap&, const SkMatrix&,
- SkBitmap* result, SkIPoint* offset) = 0;
-
- // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
- // either is identical to kNative_Premul_Config8888. Otherwise, -1.
- static const SkCanvas::Config8888 kPMColorAlias;
+ virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
+ const SkImageFilter::Context& ctx,
+ SkBitmap* result, SkIPoint* offset) {
+ return false;
+ }
protected:
+ // default impl returns NULL
+ virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&);
+
+ // default impl returns NULL
+ virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
+
+ /**
+ * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
+ * image at the specified x,y offset will fit within the device's bounds.
+ *
+ * This is explicitly asserted in readPixels(), the public way to call this.
+ */
+ virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
+
+ /**
+ * The caller is responsible for "pre-clipping" the src. The impl can assume that the src
+ * image at the specified x,y offset will fit within the device's bounds.
+ *
+ * This is explicitly asserted in writePixelsDirect(), the public way to call this.
+ */
+ virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y);
+
+ /**
+ * Default impl returns NULL.
+ */
+ virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes);
+
/**
* Leaky properties are those which the device should be applying but it isn't.
* These properties will be applied by the draw, when and as it can.
* If the device does handle a property, that property should be set to the identity value
* for that property, effectively making it non-leaky.
*/
- SkDeviceProperties fLeakyProperties;
+ const SkDeviceProperties& getLeakyProperties() const {
+ return *fLeakyProperties;
+ }
+
+ /**
+ * PRIVATE / EXPERIMENTAL -- do not call
+ * Construct an acceleration object and attach it to 'picture'
+ */
+ virtual void EXPERIMENTAL_optimize(const SkPicture* picture);
+
+ /**
+ * PRIVATE / EXPERIMENTAL -- do not call
+ * This entry point gives the backend an opportunity to take over the rendering
+ * of 'picture'. If optimization data is available (due to an earlier
+ * 'optimize' call) this entry point should make use of it and return true
+ * if all rendering has been done. If false is returned, SkCanvas will
+ * perform its own rendering pass. It is acceptable for the backend
+ * to perform some device-specific warm up tasks and then let SkCanvas
+ * perform the main rendering loop (by return false from here).
+ */
+ virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*,
+ const SkPaint*);
+
+ void setPixelGeometry(SkPixelGeometry geo);
private:
friend class SkCanvas;
friend class SkDrawIter;
friend class SkDeviceFilteredPaint;
friend class SkDeviceImageFilterProxy;
+ friend class SkDeferredDevice; // for newSurface
friend class SkSurface_Raster;
// but cannot change the width/height, so there should be no change to
// any clip information.
// TODO: move to SkBitmapDevice
- virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
+ virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
+
+ virtual bool forceConservativeRasterClip() const { return false; }
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
// just called by SkCanvas for saveLayer
- SkBaseDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
- int width, int height,
- bool isOpaque);
+ SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
- /**
- * Subclasses should override this to implement createCompatibleDevice.
- */
- virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
- int width, int height,
- bool isOpaque,
- Usage usage) = 0;
+ virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
+ return NULL;
+ }
/** Causes any deferred drawing to the device to be completed.
*/
- virtual void flush() = 0;
+ virtual void flush() {}
+
+ virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; }
SkIPoint fOrigin;
SkMetaData* fMetaData;
+ SkDeviceProperties* fLeakyProperties; // will always exist.
#ifdef SK_DEBUG
bool fAttachedToCanvas;