зеркало из https://github.com/mozilla/moz-skia.git
Protect much of SkDevice and clarify usage of drawDevice.
http://codereview.appspot.com/4798069/ git-svn-id: http://skia.googlecode.com/svn/trunk@2066 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
3f69b54d45
Коммит
88edf1e507
|
@ -16,20 +16,17 @@
|
||||||
#include "SkColor.h"
|
#include "SkColor.h"
|
||||||
|
|
||||||
class SkClipStack;
|
class SkClipStack;
|
||||||
class SkDevice;
|
|
||||||
class SkDraw;
|
class SkDraw;
|
||||||
struct SkIRect;
|
struct SkIRect;
|
||||||
class SkMatrix;
|
class SkMatrix;
|
||||||
class SkMetaData;
|
class SkMetaData;
|
||||||
class SkRegion;
|
class SkRegion;
|
||||||
|
|
||||||
// This is an opaque classes, not interpreted by skia
|
// This is an opaque class, not interpreted by skia
|
||||||
class SkGpuRenderTarget;
|
class SkGpuRenderTarget;
|
||||||
|
|
||||||
class SK_API SkDevice : public SkRefCnt {
|
class SK_API SkDevice : public SkRefCnt {
|
||||||
public:
|
public:
|
||||||
// SkDevice();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new device with the specified bitmap as its backend. It is
|
* Construct a new device with the specified bitmap as its backend. It is
|
||||||
* valid for the bitmap to have no pixels associated with it. In that case,
|
* valid for the bitmap to have no pixels associated with it. In that case,
|
||||||
|
@ -69,6 +66,8 @@ public:
|
||||||
int width, int height,
|
int width, int height,
|
||||||
bool isOpaque);
|
bool isOpaque);
|
||||||
|
|
||||||
|
SkMetaData& getMetaData();
|
||||||
|
|
||||||
enum Capabilities {
|
enum Capabilities {
|
||||||
kGL_Capability = 0x1, //!< mask indicating GL support
|
kGL_Capability = 0x1, //!< mask indicating GL support
|
||||||
kVector_Capability = 0x2, //!< mask indicating a vector representation
|
kVector_Capability = 0x2, //!< mask indicating a vector representation
|
||||||
|
@ -83,29 +82,18 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual int height() const { return fBitmap.height(); }
|
virtual int height() const { return fBitmap.height(); }
|
||||||
|
|
||||||
/**
|
/** Return the bounds of the device
|
||||||
* Return the device's origin: its offset in device coordinates from
|
|
||||||
* the default origin in its canvas' matrix/clip
|
|
||||||
*/
|
|
||||||
const SkIPoint& getOrigin() const { return fOrigin; }
|
|
||||||
|
|
||||||
/** Return the bitmap config of the device's pixels
|
|
||||||
*/
|
*/
|
||||||
SkBitmap::Config config() const { return fBitmap.getConfig(); }
|
void getBounds(SkIRect* bounds) const;
|
||||||
|
|
||||||
/** Returns true if the device's bitmap's config treats every pixels as
|
/** Returns true if the device's bitmap's config treats every pixels as
|
||||||
implicitly opaque.
|
implicitly opaque.
|
||||||
*/
|
*/
|
||||||
bool isOpaque() const { return fBitmap.isOpaque(); }
|
bool isOpaque() const { return fBitmap.isOpaque(); }
|
||||||
|
|
||||||
/** Return the bounds of the device
|
/** Return the bitmap config of the device's pixels
|
||||||
*/
|
*/
|
||||||
void getBounds(SkIRect* bounds) const;
|
SkBitmap::Config config() const { return fBitmap.getConfig(); }
|
||||||
|
|
||||||
/** Return true if the specified rectangle intersects the bounds of the
|
|
||||||
device. If sect is not NULL and there is an intersection, sect returns
|
|
||||||
the intersection.
|
|
||||||
*/
|
|
||||||
bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
|
|
||||||
|
|
||||||
/** Return the bitmap associated with this device. Call this each time you need
|
/** 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
|
to access the bitmap, as it notifies the subclass to perform any flushing
|
||||||
|
@ -115,27 +103,59 @@ public:
|
||||||
*/
|
*/
|
||||||
const SkBitmap& accessBitmap(bool changePixels);
|
const SkBitmap& accessBitmap(bool changePixels);
|
||||||
|
|
||||||
/** Clears the entire device to the specified color (including alpha).
|
/**
|
||||||
* Ignores the clip.
|
* Copy the pixels from the device into bitmap. Returns true on success.
|
||||||
|
* If false is returned, then the bitmap parameter is left unchanged.
|
||||||
|
* The bitmap parameter is treated as output-only, and will be completely
|
||||||
|
* overwritten (if the method returns true).
|
||||||
*/
|
*/
|
||||||
virtual void clear(SkColor color);
|
virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated name for clear.
|
* 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.
|
||||||
*/
|
*/
|
||||||
void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
|
virtual void writePixels(const SkBitmap& bitmap, int x, int y);
|
||||||
|
|
||||||
/** Called when this device is installed into a Canvas. Balanaced by a call
|
|
||||||
to unlockPixels() when the device is removed from a Canvas.
|
|
||||||
*/
|
|
||||||
virtual void lockPixels();
|
|
||||||
virtual void unlockPixels();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the device's associated gpu render target, or NULL.
|
* Return the device's associated gpu render target, or NULL.
|
||||||
*/
|
*/
|
||||||
virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
|
virtual SkGpuRenderTarget* accessRenderTarget() { return NULL; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum Usage {
|
||||||
|
kGeneral_Usage,
|
||||||
|
kSaveLayer_Usage, // <! internal use only
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the device's origin: its offset in device coordinates from
|
||||||
|
* the default origin in its canvas' matrix/clip
|
||||||
|
*/
|
||||||
|
const SkIPoint& getOrigin() const { return fOrigin; }
|
||||||
|
|
||||||
|
/** Return true if the specified rectangle intersects the bounds of the
|
||||||
|
device. If sect is not NULL and there is an intersection, sect returns
|
||||||
|
the intersection.
|
||||||
|
*/
|
||||||
|
bool intersects(const SkIRect& r, SkIRect* sect = NULL) const;
|
||||||
|
|
||||||
|
struct TextFlags {
|
||||||
|
uint32_t fFlags; // SkPaint::getFlags()
|
||||||
|
SkPaint::Hinting fHinting;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Device may filter the text flags for drawing text here. If it wants to
|
||||||
|
* 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 SkDevice filters based on its depth and blitters.
|
||||||
|
*/
|
||||||
|
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called with the correct matrix and clip before this device is drawn
|
* Called with the correct matrix and clip before this device is drawn
|
||||||
* to using those settings. If your subclass overrides this, be sure to
|
* to using those settings. If your subclass overrides this, be sure to
|
||||||
|
@ -157,24 +177,15 @@ public:
|
||||||
virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
|
virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
|
||||||
const SkClipStack&) {}
|
const SkClipStack&) {}
|
||||||
|
|
||||||
/** Causes any deferred drawing to the device to be completed.
|
/** Clears the entire device to the specified color (including alpha).
|
||||||
|
* Ignores the clip.
|
||||||
*/
|
*/
|
||||||
virtual void flush() {}
|
virtual void clear(SkColor color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the pixels from the device into bitmap. Returns true on success.
|
* Deprecated name for clear.
|
||||||
* If false is returned, then the bitmap parameter is left unchanged.
|
|
||||||
* The bitmap parameter is treated as output-only, and will be completely
|
|
||||||
* overwritten (if the method returns true).
|
|
||||||
*/
|
*/
|
||||||
virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
|
void eraseColor(SkColor eraseColor) { this->clear(eraseColor); }
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
virtual void writePixels(const SkBitmap& bitmap, int x, int y);
|
|
||||||
|
|
||||||
/** These are called inside the per-device-layer loop for each draw call.
|
/** These are called inside the per-device-layer loop for each draw call.
|
||||||
When these are called, we have already applied any saveLayer operations,
|
When these are called, we have already applied any saveLayer operations,
|
||||||
|
@ -224,47 +235,20 @@ public:
|
||||||
const SkColor colors[], SkXfermode* xmode,
|
const SkColor colors[], SkXfermode* xmode,
|
||||||
const uint16_t indices[], int indexCount,
|
const uint16_t indices[], int indexCount,
|
||||||
const SkPaint& paint);
|
const SkPaint& paint);
|
||||||
|
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||||
|
onCreateCompatibleDevice on this device with kSaveLayer_Usage.
|
||||||
|
*/
|
||||||
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
|
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
|
||||||
const SkPaint&);
|
const SkPaint&);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SkMetaData& getMetaData();
|
|
||||||
|
|
||||||
struct TextFlags {
|
|
||||||
uint32_t fFlags; // SkPaint::getFlags()
|
|
||||||
SkPaint::Hinting fHinting;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Device may filter the text flags for drawing text here. If it wants to
|
|
||||||
* 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 SkDevice filters based on its depth and blitters.
|
|
||||||
*/
|
|
||||||
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
/** Update as needed the pixel value in the bitmap, so that the caller can access
|
/** Update as needed the pixel value in the bitmap, so that the caller can access
|
||||||
the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
|
the pixels directly. Note: only the pixels field should be altered. The config/width/height/rowbytes
|
||||||
must remain unchanged.
|
must remain unchanged.
|
||||||
*/
|
*/
|
||||||
virtual void onAccessBitmap(SkBitmap*);
|
virtual void onAccessBitmap(SkBitmap*);
|
||||||
|
|
||||||
enum Usage {
|
|
||||||
kGeneral_Usage,
|
|
||||||
kSaveLayer_Usage, // <! internal use only
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* subclasses should override this to implement createCompatibleDevice.
|
|
||||||
*/
|
|
||||||
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
|
||||||
int width, int height,
|
|
||||||
bool isOpaque,
|
|
||||||
Usage usage);
|
|
||||||
|
|
||||||
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
|
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
|
||||||
// just for subclasses, to assign a custom pixelref
|
// just for subclasses, to assign a custom pixelref
|
||||||
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
|
SkPixelRef* setPixelRef(SkPixelRef* pr, size_t offset) {
|
||||||
|
@ -272,8 +256,19 @@ protected:
|
||||||
return pr;
|
return pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called when this device is installed into a Canvas. Balanaced by a call
|
||||||
|
to unlockPixels() when the device is removed from a Canvas.
|
||||||
|
*/
|
||||||
|
virtual void lockPixels();
|
||||||
|
virtual void unlockPixels();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SkCanvas;
|
friend class SkCanvas;
|
||||||
|
friend struct DeviceCM; //for setMatrixClip
|
||||||
|
friend class SkDraw;
|
||||||
|
friend class SkDrawIter;
|
||||||
|
friend class SkDeviceFilteredPaint;
|
||||||
|
|
||||||
// just called by SkCanvas when built as a layer
|
// just called by SkCanvas when built as a layer
|
||||||
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
void setOrigin(int x, int y) { fOrigin.set(x, y); }
|
||||||
// just called by SkCanvas for saveLayer
|
// just called by SkCanvas for saveLayer
|
||||||
|
@ -281,6 +276,18 @@ private:
|
||||||
int width, int height,
|
int width, int height,
|
||||||
bool isOpaque);
|
bool isOpaque);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses should override this to implement createCompatibleDevice.
|
||||||
|
*/
|
||||||
|
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
|
||||||
|
int width, int height,
|
||||||
|
bool isOpaque,
|
||||||
|
Usage usage);
|
||||||
|
|
||||||
|
/** Causes any deferred drawing to the device to be completed.
|
||||||
|
*/
|
||||||
|
virtual void flush() {}
|
||||||
|
|
||||||
SkBitmap fBitmap;
|
SkBitmap fBitmap;
|
||||||
SkIPoint fOrigin;
|
SkIPoint fOrigin;
|
||||||
SkMetaData* fMetaData;
|
SkMetaData* fMetaData;
|
||||||
|
|
|
@ -70,6 +70,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void setMatrixClip(const SkMatrix& m, const SkRegion& r,
|
||||||
|
const SkClipStack& c)
|
||||||
|
{
|
||||||
|
SkDevice::setMatrixClip(m, r, c);
|
||||||
|
}
|
||||||
|
|
||||||
/** These are called inside the per-device-layer loop for each draw call.
|
/** These are called inside the per-device-layer loop for each draw call.
|
||||||
When these are called, we have already applied any saveLayer operations,
|
When these are called, we have already applied any saveLayer operations,
|
||||||
and are handling any looping from the paint, and any effects from the
|
and are handling any looping from the paint, and any effects from the
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct DeviceCM {
|
||||||
const SkMatrix* fMVMatrix;
|
const SkMatrix* fMVMatrix;
|
||||||
const SkMatrix* fExtMatrix;
|
const SkMatrix* fExtMatrix;
|
||||||
|
|
||||||
DeviceCM(SkDevice* device, int x, int y, const SkPaint* paint)
|
DeviceCM(SkDevice* device, int x, int y, const SkPaint* paint)
|
||||||
: fNext(NULL) {
|
: fNext(NULL) {
|
||||||
if (NULL != device) {
|
if (NULL != device) {
|
||||||
device->ref();
|
device->ref();
|
||||||
|
@ -79,15 +79,15 @@ struct DeviceCM {
|
||||||
}
|
}
|
||||||
fDevice = device;
|
fDevice = device;
|
||||||
fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
|
fPaint = paint ? SkNEW_ARGS(SkPaint, (*paint)) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~DeviceCM() {
|
~DeviceCM() {
|
||||||
if (NULL != fDevice) {
|
if (NULL != fDevice) {
|
||||||
fDevice->unlockPixels();
|
fDevice->unlockPixels();
|
||||||
fDevice->unref();
|
fDevice->unref();
|
||||||
}
|
}
|
||||||
SkDELETE(fPaint);
|
SkDELETE(fPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip,
|
void updateMC(const SkMatrix& totalMatrix, const SkRegion& totalClip,
|
||||||
const SkClipStack& clipStack, SkRegion* updateClip) {
|
const SkClipStack& clipStack, SkRegion* updateClip) {
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
reference counted, since the real owner is either our fLayer field,
|
reference counted, since the real owner is either our fLayer field,
|
||||||
or a previous one in a lower level.)
|
or a previous one in a lower level.)
|
||||||
*/
|
*/
|
||||||
DeviceCM* fTopLayer;
|
DeviceCM* fTopLayer;
|
||||||
|
|
||||||
MCRec(const MCRec* prev, int flags) {
|
MCRec(const MCRec* prev, int flags) {
|
||||||
if (NULL != prev) {
|
if (NULL != prev) {
|
||||||
|
@ -749,7 +749,7 @@ void SkCanvas::internalRestore() {
|
||||||
fLocalBoundsCompareTypeDirtyBW = true;
|
fLocalBoundsCompareTypeDirtyBW = true;
|
||||||
|
|
||||||
fClipStack.restore();
|
fClipStack.restore();
|
||||||
// reserve our layer (if any)
|
// reserve our layer (if any)
|
||||||
DeviceCM* layer = fMCRec->fLayer; // may be null
|
DeviceCM* layer = fMCRec->fLayer; // may be null
|
||||||
// now detach it from fMCRec so we can pop(). Gets freed after its drawn
|
// now detach it from fMCRec so we can pop(). Gets freed after its drawn
|
||||||
fMCRec->fLayer = NULL;
|
fMCRec->fLayer = NULL;
|
||||||
|
@ -772,7 +772,7 @@ void SkCanvas::internalRestore() {
|
||||||
fDeviceCMDirty = true;
|
fDeviceCMDirty = true;
|
||||||
}
|
}
|
||||||
SkDELETE(layer);
|
SkDELETE(layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkASSERT(fClipStack.getSaveCount() == this->getSaveCount() - 1);
|
SkASSERT(fClipStack.getSaveCount() == this->getSaveCount() - 1);
|
||||||
}
|
}
|
||||||
|
@ -1153,7 +1153,7 @@ void SkCanvas::setExternalMatrix(const SkMatrix* matrix) {
|
||||||
SkDevice* SkCanvas::createLayerDevice(SkBitmap::Config config,
|
SkDevice* SkCanvas::createLayerDevice(SkBitmap::Config config,
|
||||||
int width, int height,
|
int width, int height,
|
||||||
bool isOpaque) {
|
bool isOpaque) {
|
||||||
SkDevice* device = this->getDevice();
|
SkDevice* device = this->getTopDevice();
|
||||||
if (device) {
|
if (device) {
|
||||||
return device->createCompatibleDeviceForSaveLayer(config, width, height,
|
return device->createCompatibleDeviceForSaveLayer(config, width, height,
|
||||||
isOpaque);
|
isOpaque);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче