diff options
Diffstat (limited to 'include')
48 files changed, 1150 insertions, 454 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h index 24e4141..1b9f055 100644 --- a/include/core/SkCanvas.h +++ b/include/core/SkCanvas.h @@ -62,6 +62,11 @@ public: /////////////////////////////////////////////////////////////////////////// /** + * Trigger the immediate execution of all pending draw operations. + */ + void flush(); + + /** * Return the width/height of the underlying device. The current drawable * area may be small (due to clipping or saveLayer). For a canvas with * no device, 0,0 will be returned. @@ -78,7 +83,7 @@ public: reference count is incremented. If the canvas was already holding a device, its reference count is decremented. The new device is returned. */ - SkDevice* setDevice(SkDevice* device); + virtual SkDevice* setDevice(SkDevice* device); /** * saveLayer() can create another device (which is later drawn onto @@ -99,7 +104,7 @@ public: * Shortcut for getDevice()->createCompatibleDevice(...). * If getDevice() == NULL, this method does nothing, and returns NULL. */ - SkDevice* createCompatibleDevice(SkBitmap::Config config, + SkDevice* createCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque); @@ -152,7 +157,7 @@ public: * kARGB_8888_Config as SkPMColor * * If the bitmap has pixels already allocated, the canvas pixels will be - * written there. If not, bitmap->allocPixels() will be called + * written there. If not, bitmap->allocPixels() will be called * automatically. If the bitmap is backed by a texture readPixels will * fail. * @@ -290,7 +295,7 @@ public: /** Returns true if drawing is currently going to a layer (from saveLayer) * rather than to the root device. */ - bool isDrawingToLayer() const; + virtual bool isDrawingToLayer() const; /** Preconcat the current matrix with the specified translation @param dx The distance to translate in X @@ -424,7 +429,16 @@ public: @return true if the horizontal band is completely clipped out (i.e. does not intersect the current clip) */ - bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const; + bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const { + SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom)); + const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et); + // In the case where the clip is empty and we are provided with a + // negative top and positive bottom parameter then this test will return + // false even though it will be clipped. We have chosen to exclude that + // check as it is rare and would result double the comparisons. + return SkScalarToCompareType(top) >= clipR.fBottom + || SkScalarToCompareType(bottom) <= clipR.fTop; + } /** Return the bounds of the current clip (in local coordinates) in the bounds parameter, and return true if it is non-empty. This can be useful @@ -438,7 +452,7 @@ public: then taking its bounds. */ bool getClipDeviceBounds(SkIRect* bounds) const; - + /** Fill the entire canvas' bitmap (restricted to the current clip) with the specified ARGB color, using the specified mode. @@ -921,10 +935,21 @@ public: }; protected: + // Returns the canvas to be used by DrawIter. Default implementation + // returns this. Subclasses that encapsulate an indirect canvas may + // need to overload this method. The impl must keep track of this, as it + // is not released or deleted by the caller. + virtual SkCanvas* canvasForDrawIter(); + // all of the drawBitmap variants call this guy virtual void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&, const SkPaint& paint); + // Clip rectangle bounds. Called internally by saveLayer. + // returns false if the entire rectangle is entirely clipped out + bool clipRectBounds(const SkRect* bounds, SaveFlags flags, + SkIRect* intersection); + private: class MCRec; @@ -947,7 +972,7 @@ private: friend class SkDrawIter; // needs setupDrawForLayerDevice() - SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, + SkDevice* createLayerDevice(SkBitmap::Config, int width, int height, bool isOpaque); SkDevice* init(SkDevice*); @@ -962,7 +987,7 @@ private: const SkRect& dst, const SkPaint* paint); void internalDrawPaint(const SkPaint& paint); - + void drawDevice(SkDevice*, int x, int y, const SkPaint*); // shared by save() and saveLayer() int internalSave(SaveFlags flags); diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h index 714e845..e51b0b9 100644 --- a/include/core/SkColorPriv.h +++ b/include/core/SkColorPriv.h @@ -216,6 +216,57 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { } /** + * Abstract 4-byte interpolation, implemented on top of SkPMColor + * utility functions. Third parameter controls blending of the first two: + * (src, dst, 0) returns dst + * (src, dst, 0xFF) returns src + */ +static inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, + U8CPU srcWeight) { + unsigned scale = SkAlpha255To256(srcWeight); + + unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale); + unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale); + unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale); + unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale); + + return SkPackARGB32(a, r, g, b); +} + +/** + * 32b optimized version; currently appears to be 10% faster even on 64b + * architectures than an equivalent 64b version and 30% faster than + * SkFourByteInterp(). Third parameter controls blending of the first two: + * (src, dst, 0) returns dst + * (src, dst, 0xFF) returns src + * ** Does not match the results of SkFourByteInterp() because we use + * a more accurate scale computation! + * TODO: migrate Skia function to using an accurate 255->266 alpha + * conversion. + */ +static inline SkPMColor SkFastFourByteInterp(SkPMColor src, + SkPMColor dst, + U8CPU srcWeight) { + SkASSERT(srcWeight < 256); + + // Reorders ARGB to AG-RB in order to reduce the number of operations. + const uint32_t mask = 0xFF00FF; + uint32_t src_rb = src & mask; + uint32_t src_ag = (src >> 8) & mask; + uint32_t dst_rb = dst & mask; + uint32_t dst_ag = (dst >> 8) & mask; + + // scale = srcWeight + (srcWeight >> 7) is more accurate than + // scale = srcWeight + 1, but 7% slower + int scale = srcWeight + (srcWeight >> 7); + + uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb; + uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag; + + return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8); +} + +/** * Same as SkPackARGB32, but this version guarantees to not check that the * values are premultiplied in the debug version. */ @@ -663,5 +714,116 @@ static inline uint32_t SkExpand32_4444(SkPMColor c) { // used for cheap 2x2 dithering when the colors are opaque void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n); +/////////////////////////////////////////////////////////////////////////////// + +static inline int SkUpscale31To32(int value) { + SkASSERT((unsigned)value <= 31); + return value + (value >> 4); +} + +static inline int SkBlend32(int src, int dst, int scale) { + SkASSERT((unsigned)src <= 0xFF); + SkASSERT((unsigned)dst <= 0xFF); + SkASSERT((unsigned)scale <= 32); + return dst + ((src - dst) * scale >> 5); +} + +static inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB, + SkPMColor dst, uint16_t mask) { + if (mask == 0) { + return dst; + } + + /* We want all of these in 5bits, hence the shifts in case one of them + * (green) is 6bits. + */ + int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); + int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); + int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); + + // Now upscale them to 0..32, so we can use blend32 + maskR = SkUpscale31To32(maskR); + maskG = SkUpscale31To32(maskG); + maskB = SkUpscale31To32(maskB); + + // srcA has been upscaled to 256 before passed into this function + maskR = maskR * srcA >> 8; + maskG = maskG * srcA >> 8; + maskB = maskB * srcA >> 8; + + int dstR = SkGetPackedR32(dst); + int dstG = SkGetPackedG32(dst); + int dstB = SkGetPackedB32(dst); + + // LCD blitting is only supported if the dst is known/required + // to be opaque + return SkPackARGB32(0xFF, + SkBlend32(srcR, dstR, maskR), + SkBlend32(srcG, dstG, maskG), + SkBlend32(srcB, dstB, maskB)); +} + +static inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB, + SkPMColor dst, uint16_t mask, + SkPMColor opaqueDst) { + if (mask == 0) { + return dst; + } + + if (0xFFFF == mask) { + return opaqueDst; + } + + /* We want all of these in 5bits, hence the shifts in case one of them + * (green) is 6bits. + */ + int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5); + int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5); + int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5); + + // Now upscale them to 0..32, so we can use blend32 + maskR = SkUpscale31To32(maskR); + maskG = SkUpscale31To32(maskG); + maskB = SkUpscale31To32(maskB); + + int dstR = SkGetPackedR32(dst); + int dstG = SkGetPackedG32(dst); + int dstB = SkGetPackedB32(dst); + + // LCD blitting is only supported if the dst is known/required + // to be opaque + return SkPackARGB32(0xFF, + SkBlend32(srcR, dstR, maskR), + SkBlend32(srcG, dstG, maskG), + SkBlend32(srcB, dstB, maskB)); +} + +static inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[], + SkColor color, int width, SkPMColor) { + int srcA = SkColorGetA(color); + int srcR = SkColorGetR(color); + int srcG = SkColorGetG(color); + int srcB = SkColorGetB(color); + + srcA = SkAlpha255To256(srcA); + + for (int i = 0; i < width; i++) { + dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]); + } +} + +static inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[], + SkColor color, int width, + SkPMColor opaqueDst) { + int srcR = SkColorGetR(color); + int srcG = SkColorGetG(color); + int srcB = SkColorGetB(color); + + for (int i = 0; i < width; i++) { + dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i], + opaqueDst); + } +} + #endif diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h index c026a4b..3303981 100644 --- a/include/core/SkDevice.h +++ b/include/core/SkDevice.h @@ -62,7 +62,7 @@ public: * draw into this device such that all of the pixels will * be opaque. */ - SkDevice* createCompatibleDevice(SkBitmap::Config config, + SkDevice* createCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque); @@ -258,7 +258,7 @@ protected: * 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 + * written there. If not, bitmap->allocPixels() will be called * automatically. If the bitmap is backed by a texture readPixels will * fail. * @@ -279,11 +279,14 @@ protected: /////////////////////////////////////////////////////////////////////////// - /** 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 - must remain unchanged. + /** 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 must remain unchanged. + @param bitmap The device's bitmap + @return Echo the bitmap parameter, or an alternate (shadow) bitmap + maintained by the subclass. */ - virtual void onAccessBitmap(SkBitmap*); + virtual const SkBitmap& onAccessBitmap(SkBitmap*); SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } // just for subclasses, to assign a custom pixelref @@ -291,7 +294,7 @@ protected: fBitmap.setPixelRef(pr, offset); return pr; } - + /** * Implements readPixels API. The caller will ensure that: * 1. bitmap has pixel config kARGB_8888_Config. @@ -327,7 +330,7 @@ protected: const SkMatrix& ctm, SkBitmap* result, SkIPoint* offset); - // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if + // 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; @@ -342,15 +345,15 @@ private: // 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 - SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config, + SkDevice* createCompatibleDeviceForSaveLayer(SkBitmap::Config config, int width, int height, bool isOpaque); /** * Subclasses should override this to implement createCompatibleDevice. */ - virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, + virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, + int width, int height, bool isOpaque, Usage usage); diff --git a/include/core/SkDeviceProfile.h b/include/core/SkDeviceProfile.h new file mode 100644 index 0000000..46b9781 --- /dev/null +++ b/include/core/SkDeviceProfile.h @@ -0,0 +1,95 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkDeviceProfile_DEFINED +#define SkDeviceProfile_DEFINED + +#include "SkRefCnt.h" + +class SkDeviceProfile : public SkRefCnt { +public: + enum LCDConfig { + kNone_LCDConfig, // disables LCD text rendering, uses A8 instead + kRGB_Horizontal_LCDConfig, + kBGR_Horizontal_LCDConfig, + kRGB_Vertical_LCDConfig, + kBGR_Vertical_LCDConfig, + }; + + enum FontHintLevel { + kNone_FontHintLevel, + kSlight_FontHintLevel, + kNormal_FontHintLevel, + kFull_FontHintLevel, + kAuto_FontHintLevel, + }; + + /** + * gammaExp is typically between 1.0 and 2.2. For no gamma adjustment, + * specify 1.0 + * + * contrastScale will be pinned between 0.0 and 1.0. For no contrast + * adjustment, specify 0.0 + * + * @param config Describes the LCD layout for this device. If this is set + * to kNone, then all requests for LCD text will be + * devolved to A8 antialiasing. + * + * @param level The hinting level to be used, IF the paint specifies + * "default". Otherwise the paint's hinting level will be + * respected. + */ + static SkDeviceProfile* Create(float gammaExp, + float contrastScale, + LCDConfig, + FontHintLevel); + + /** + * Returns the global default profile, that is used if no global profile is + * specified with SetGlobal(), or if NULL is specified to SetGlobal(). + * The references count is *not* incremented, and the caller should not + * call unref(). + */ + static SkDeviceProfile* GetDefault(); + + /** + * Return the current global profile (or the default if no global had yet + * been set) and increment its reference count. The call *must* call unref() + * when it is done using it. + */ + static SkDeviceProfile* RefGlobal(); + + /** + * Make the specified profile be the global value for all subsequently + * instantiated devices. Does not affect any existing devices. + * Increments the reference count on the profile. + * Specify NULL for the "identity" profile (where there is no gamma or + * contrast correction). + */ + static void SetGlobal(SkDeviceProfile*); + + float getFontGammaExponent() const { return fGammaExponent; } + float getFontContrastScale() const { return fContrastScale; } + + /** + * Given a luminance byte (0 for black, 0xFF for white), generate a table + * that applies the gamma/contrast settings to linear coverage values. + */ + void generateTableForLuminanceByte(U8CPU lumByte, uint8_t table[256]) const; + +private: + SkDeviceProfile(float gammaExp, float contrastScale, LCDConfig, + FontHintLevel); + + float fGammaExponent; + float fContrastScale; + LCDConfig fLCDConfig; + FontHintLevel fFontHintLevel; +}; + +#endif + diff --git a/include/core/SkEndian.h b/include/core/SkEndian.h index 3eb67da..910cf1e 100644 --- a/include/core/SkEndian.h +++ b/include/core/SkEndian.h @@ -31,8 +31,11 @@ */ static inline uint16_t SkEndianSwap16(U16CPU value) { SkASSERT(value == (uint16_t)value); - return (uint16_t)((value >> 8) | (value << 8)); + return static_cast<uint16_t>((value >> 8) | (value << 8)); } +template<uint16_t N> struct SkTEndianSwap16 { + static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8)); +}; /** Vector version of SkEndianSwap16(), which swaps the low two bytes of each value in the array. @@ -55,6 +58,12 @@ static inline uint32_t SkEndianSwap32(uint32_t value) { ((value & 0xFF0000) >> 8) | (value >> 24); } +template<uint32_t N> struct SkTEndianSwap32 { + static const uint32_t value = ((N & 0xFF) << 24) | + ((N & 0xFF00) << 8) | + ((N & 0xFF0000) >> 8) | + (N >> 24); +}; /** Vector version of SkEndianSwap16(), which swaps the bytes of each value in the array. @@ -73,11 +82,21 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) { #define SkEndian_SwapBE32(n) SkEndianSwap32(n) #define SkEndian_SwapLE16(n) (n) #define SkEndian_SwapLE32(n) (n) + + #define SkTEndian_SwapBE16(n) SkTEndianSwap16<n>::value + #define SkTEndian_SwapBE32(n) SkTEndianSwap32<n>::value + #define SkTEndian_SwapLE16(n) (n) + #define SkTEndian_SwapLE32(n) (n) #else // SK_CPU_BENDIAN #define SkEndian_SwapBE16(n) (n) #define SkEndian_SwapBE32(n) (n) #define SkEndian_SwapLE16(n) SkEndianSwap16(n) #define SkEndian_SwapLE32(n) SkEndianSwap32(n) + + #define SkTEndian_SwapBE16(n) (n) + #define SkTEndian_SwapBE32(n) (n) + #define SkTEndian_SwapLE16(n) SkTEndianSwap16<n>::value + #define SkTEndian_SwapLE32(n) SkTEndianSwap32<n>::value #endif // When a bytestream is embedded in a 32-bit word, how far we need to @@ -94,5 +113,40 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) { #define SkEndian_Byte3Shift 0 #endif + +#if defined(SK_UINT8_BITFIELD_LENDIAN) && defined(SK_UINT8_BITFIELD_BENDIAN) + #error "can't have both bitfield LENDIAN and BENDIAN defined" +#endif + +#if !defined(SK_UINT8_BITFIELD_LENDIAN) && !defined(SK_UINT8_BITFIELD_BENDIAN) + #ifdef SK_CPU_LENDIAN + #define SK_UINT8_BITFIELD_LENDIAN + #else + #define SK_UINT8_BITFIELD_BENDIAN + #endif +#endif + +#ifdef SK_UINT8_BITFIELD_LENDIAN + #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ + SK_OT_BYTE f0 : 1; \ + SK_OT_BYTE f1 : 1; \ + SK_OT_BYTE f2 : 1; \ + SK_OT_BYTE f3 : 1; \ + SK_OT_BYTE f4 : 1; \ + SK_OT_BYTE f5 : 1; \ + SK_OT_BYTE f6 : 1; \ + SK_OT_BYTE f7 : 1; +#else + #define SK_UINT8_BITFIELD(f0, f1, f2, f3, f4, f5, f6, f7) \ + SK_OT_BYTE f7 : 1; \ + SK_OT_BYTE f6 : 1; \ + SK_OT_BYTE f5 : 1; \ + SK_OT_BYTE f4 : 1; \ + SK_OT_BYTE f3 : 1; \ + SK_OT_BYTE f2 : 1; \ + SK_OT_BYTE f1 : 1; \ + SK_OT_BYTE f0 : 1; +#endif + #endif diff --git a/include/core/SkFontHost.h b/include/core/SkFontHost.h index c549519..25c9ecb 100644 --- a/include/core/SkFontHost.h +++ b/include/core/SkFontHost.h @@ -84,12 +84,6 @@ public: /////////////////////////////////////////////////////////////////////////// - /** Returns true if the specified unique ID matches an existing font. - Returning false is similar to calling OpenStream with an invalid ID, - which will return NULL in that case. - */ - static bool ValidFontID(SkFontID uniqueID); - /** Return a new stream to read the font data, or null if the uniqueID does not match an existing typeface. .The caller must call stream->unref() when it is finished reading the data. diff --git a/include/core/SkImageFilter.h b/include/core/SkImageFilter.h index 22b9569..7d7c140 100644 --- a/include/core/SkImageFilter.h +++ b/include/core/SkImageFilter.h @@ -80,6 +80,22 @@ public: */ virtual bool asABlur(SkSize* sigma) const; + /** + * Experimental. + * + * If the filter can be expressed as an erode, return true and + * set the radius in X and Y. + */ + virtual bool asAnErode(SkISize* radius) const; + + /** + * Experimental. + * + * If the filter can be expressed as a dilation, return true and + * set the radius in X and Y. + */ + virtual bool asADilate(SkISize* radius) const; + protected: SkImageFilter() {} explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {} diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 445f7eb..31bc30b 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -100,11 +100,12 @@ public: kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter kVerticalText_Flag = 0x1000, + kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it // when adding extra flags, note that the fFlags member is specified // with a bit-width and you'll have to expand it. - kAllFlags = 0x1FFF + kAllFlags = 0x3FFF }; /** Return the paint's flags. Use the Flag enum to test flag values. @@ -880,7 +881,7 @@ private: SkColor fColor; SkScalar fWidth; SkScalar fMiterLimit; - unsigned fFlags : 14; + unsigned fFlags : 15; unsigned fTextAlign : 2; unsigned fCapType : 2; unsigned fJoinType : 2; diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 536e887..957d50e 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -742,6 +742,7 @@ private: SkTDArray<SkPoint> fPts; SkTDArray<uint8_t> fVerbs; mutable SkRect fBounds; + int fLastMoveToIndex; uint8_t fFillType; uint8_t fSegmentMask; mutable uint8_t fBoundsIsDirty; @@ -755,7 +756,6 @@ private: void computeBounds() const; friend class Iter; - void cons_moveto(); friend class SkPathStroker; /* Append the first contour of path, ignoring path's initial point. If no @@ -770,7 +770,14 @@ private: */ void reversePathTo(const SkPath&); - friend const SkPoint* sk_get_path_points(const SkPath&, int index); + // called before we add points for lineTo, quadTo, cubicTo, checking to see + // if we need to inject a leading moveTo first + // + // SkPath path; path.lineTo(...); <--- need a leading moveTo(0, 0) + // SkPath path; ... path.close(); path.lineTo(...) <-- need a moveTo(previous moveTo) + // + inline void injectMoveToIfNeeded(); + friend class SkAutoPathBoundsUpdate; }; diff --git a/include/core/SkPathMeasure.h b/include/core/SkPathMeasure.h index ec43834..6fb4482 100644 --- a/include/core/SkPathMeasure.h +++ b/include/core/SkPathMeasure.h @@ -85,13 +85,14 @@ private: struct Segment { SkScalar fDistance; // total distance up to this point - unsigned fPtIndex : 15; + unsigned fPtIndex : 15; // index into the fPts array unsigned fTValue : 15; unsigned fType : 2; SkScalar getScalarT() const; }; SkTDArray<Segment> fSegments; + SkTDArray<SkPoint> fPts; // Points used to define the segments static const Segment* NextSegment(const Segment*); @@ -104,4 +105,3 @@ private: }; #endif - diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h index e247479..d5f6ab2 100644 --- a/include/core/SkPixelRef.h +++ b/include/core/SkPixelRef.h @@ -50,9 +50,9 @@ class SkGpuTexture; This class can be shared/accessed between multiple threads. */ -class SkPixelRef : public SkRefCnt { +class SK_API SkPixelRef : public SkRefCnt { public: - explicit SkPixelRef(SkMutex* mutex = NULL); + explicit SkPixelRef(SkBaseMutex* mutex = NULL); /** Return the pixel memory returned from lockPixels, or null if the lockCount is 0. @@ -201,16 +201,16 @@ protected: /** Return the mutex associated with this pixelref. This value is assigned in the constructor, and cannot change during the lifetime of the object. */ - SkMutex* mutex() const { return fMutex; } + SkBaseMutex* mutex() const { return fMutex; } - SkPixelRef(SkFlattenableReadBuffer&, SkMutex*); + SkPixelRef(SkFlattenableReadBuffer&, SkBaseMutex*); private: #if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS static void InitializeFlattenables(); #endif - SkMutex* fMutex; // must remain in scope for the life of this object + SkBaseMutex* fMutex; // must remain in scope for the life of this object void* fPixels; SkColorTable* fColorTable; // we do not track ownership, subclass does int fLockCount; diff --git a/include/core/SkPoint.h b/include/core/SkPoint.h index de7c0ef..d371e64 100644 --- a/include/core/SkPoint.h +++ b/include/core/SkPoint.h @@ -442,11 +442,11 @@ struct SK_API SkPoint { void setOrthog(const SkPoint& vec, Side side = kLeft_Side) { // vec could be this SkScalar tmp = vec.fX; - if (kLeft_Side == side) { + if (kRight_Side == side) { fX = -vec.fY; fY = tmp; } else { - SkASSERT(kRight_Side == side); + SkASSERT(kLeft_Side == side); fX = vec.fY; fY = -tmp; } diff --git a/include/core/SkRegion.h b/include/core/SkRegion.h index 9d89d94..7623b82 100644 --- a/include/core/SkRegion.h +++ b/include/core/SkRegion.h @@ -45,13 +45,13 @@ public: * Return true if the two regions are equal. i.e. The enclose exactly * the same area. */ - friend bool operator==(const SkRegion& a, const SkRegion& b); + bool operator==(const SkRegion& other) const; /** * Return true if the two regions are not equal. */ - friend bool operator!=(const SkRegion& a, const SkRegion& b) { - return !(a == b); + bool operator!=(const SkRegion& other) const { + return !(*this == other); } /** diff --git a/include/core/SkScalerContext.h b/include/core/SkScalerContext.h index e7dd7d4..29679d6 100644 --- a/include/core/SkScalerContext.h +++ b/include/core/SkScalerContext.h @@ -16,6 +16,8 @@ #include "SkPath.h" #include "SkPoint.h" +//#define SK_USE_COLOR_LUMINANCE + class SkDescriptor; class SkMaskFilter; class SkPathEffect; @@ -175,16 +177,27 @@ public: kLCD_Vertical_Flag = 0x0200, // else Horizontal kLCD_BGROrder_Flag = 0x0400, // else RGB order + // Generate A8 from LCD source (for GDI), only meaningful if fMaskFormat is kA8 + // Perhaps we can store this (instead) in fMaskFormat, in hight bit? + kGenA8FromLCD_Flag = 0x0800, + +#ifdef SK_USE_COLOR_LUMINANCE + kLuminance_Bits = 3, +#else // luminance : 0 for black text, kLuminance_Max for white text - kLuminance_Shift = 11, // to shift into the other flags above + kLuminance_Shift = 13, // shift to land in the high 3-bits of Flags kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits +#endif }; // computed values enum { kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag, +#ifdef SK_USE_COLOR_LUMINANCE +#else kLuminance_Max = (1 << kLuminance_Bits) - 1, kLuminance_Mask = kLuminance_Max << kLuminance_Shift, +#endif }; struct Rec { @@ -193,6 +206,9 @@ public: SkScalar fTextSize, fPreScaleX, fPreSkewX; SkScalar fPost2x2[2][2]; SkScalar fFrameWidth, fMiterLimit; +#ifdef SK_USE_COLOR_LUMINANCE + uint32_t fLumBits; +#endif uint8_t fMaskFormat; uint8_t fStrokeJoin; uint16_t fFlags; @@ -213,7 +229,20 @@ public: void setHinting(SkPaint::Hinting hinting) { fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift); } - + + SkMask::Format getFormat() const { + return static_cast<SkMask::Format>(fMaskFormat); + } + +#ifdef SK_USE_COLOR_LUMINANCE + SkColor getLuminanceColor() const { + return fLumBits; + } + + void setLuminanceColor(SkColor c) { + fLumBits = c; + } +#else unsigned getLuminanceBits() const { return (fFlags & kLuminance_Mask) >> kLuminance_Shift; } @@ -230,10 +259,7 @@ public: lum |= (lum << kLuminance_Bits*2); return lum >> (4*kLuminance_Bits - 8); } - - SkMask::Format getFormat() const { - return static_cast<SkMask::Format>(fMaskFormat); - } +#endif }; SkScalerContext(const SkDescriptor* desc); @@ -277,6 +303,8 @@ public: #endif static inline void MakeRec(const SkPaint&, const SkMatrix*, Rec* rec); + static inline void PostMakeRec(Rec*); + static SkScalerContext* Create(const SkDescriptor*); protected: diff --git a/include/core/SkStream.h b/include/core/SkStream.h index 90d2357..67512d7 100644 --- a/include/core/SkStream.h +++ b/include/core/SkStream.h @@ -272,7 +272,8 @@ class SkMemoryWStream : public SkWStream { public: SkMemoryWStream(void* buffer, size_t size); virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - + size_t bytesWritten() const { return fBytesWritten; } + private: char* fBuffer; size_t fMaxLength; diff --git a/include/core/SkStroke.h b/include/core/SkStroke.h index d055b83..e5d69c4 100644 --- a/include/core/SkStroke.h +++ b/include/core/SkStroke.h @@ -16,10 +16,6 @@ struct SkRect; class SkPath; -#define SK_DefaultStrokeWidth SK_Scalar1 -#define SK_DefaultMiterLimit SkIntToScalar(4) - - /** \class SkStroke SkStroke is the utility class that constructs paths by stroking geometries (lines, rects, ovals, roundrects, paths). This is diff --git a/include/core/SkThread.h b/include/core/SkThread.h index 5f2da4a..1495a16 100644 --- a/include/core/SkThread.h +++ b/include/core/SkThread.h @@ -31,7 +31,7 @@ public: class SkAutoMutexAcquire : SkNoncopyable { public: - explicit SkAutoMutexAcquire(SkMutex& mutex) : fMutex(&mutex) + explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) { SkASSERT(fMutex != NULL); mutex.acquire(); @@ -55,7 +55,7 @@ public: } private: - SkMutex* fMutex; + SkBaseMutex* fMutex; }; #endif diff --git a/include/core/SkThread_platform.h b/include/core/SkThread_platform.h index d83f3ed..863f6e3 100644 --- a/include/core/SkThread_platform.h +++ b/include/core/SkThread_platform.h @@ -53,38 +53,44 @@ SK_API int32_t sk_atomic_dec(int32_t* addr); #endif // !SK_BUILD_FOR_ANDROID -#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) +#ifdef SK_USE_POSIX_THREADS + +#include <pthread.h> + +// A SkBaseMutex is a POD structure that can be directly initialized +// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the +// generation of a static initializer in the final machine code (and +// a corresponding static finalizer). +// +struct SkBaseMutex { + void acquire() { pthread_mutex_lock(&fMutex); } + void release() { pthread_mutex_unlock(&fMutex); } + pthread_mutex_t fMutex; +}; -#include <utils/threads.h> +// Using POD-style initialization prevents the generation of a static initializer +// and keeps the acquire() implementation small and fast. +#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } -class SkMutex : android::Mutex { -public: - // if isGlobal is true, then ignore any errors in the platform-specific - // destructor - SkMutex(bool isGlobal = true) {} - ~SkMutex() {} +// Special case used when the static mutex must be available globally. +#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } - void acquire() { this->lock(); } - void release() { this->unlock(); } +// A normal mutex that requires to be initialized through normal C++ construction, +// i.e. when it's a member of another class, or allocated on the heap. +class SkMutex : public SkBaseMutex, SkNoncopyable { +public: + SkMutex(); + ~SkMutex(); }; -#else - -/** Implemented by the porting layer, this function adds 1 to the int specified - by the address (in a thread-safe manner), and returns the previous value. -*/ -SK_API int32_t sk_atomic_inc(int32_t* addr); -/** Implemented by the porting layer, this function subtracts 1 to the int - specified by the address (in a thread-safe manner), and returns the previous - value. -*/ -SK_API int32_t sk_atomic_dec(int32_t* addr); +#else // !SK_USE_POSIX_THREADS -class SkMutex { +// In the generic case, SkBaseMutex and SkMutex are the same thing, and we +// can't easily get rid of static initializers. +// +class SkMutex : SkNoncopyable { public: - // if isGlobal is true, then ignore any errors in the platform-specific - // destructor - SkMutex(bool isGlobal = true); + SkMutex(); ~SkMutex(); void acquire(); @@ -98,6 +104,12 @@ private: uint32_t fStorage[kStorageIntCount]; }; -#endif +typedef SkMutex SkBaseMutex; + +#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name +#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name + +#endif // !SK_USE_POSIX_THREADS + #endif diff --git a/include/core/SkUserConfig.h b/include/core/SkUserConfig.h index 4bcf2e3..ef75114 100644 --- a/include/core/SkUserConfig.h +++ b/include/core/SkUserConfig.h @@ -49,6 +49,8 @@ #include <utils/misc.h> #endif +#define SK_USE_POSIX_THREADS + /* Scalars (the fractional value type in skia) can be implemented either as floats or 16.16 integers (fixed). Exactly one of these two symbols must be defined. @@ -114,7 +116,7 @@ printf conventions (e.g. const char* format, ...). If you want to redirect this to something other than printf, define yours here */ -//#define SkDebugf(...) MyFunction(__VA_ARGS__) +//#define SkDebugf(...) MyFunction(__VA_ARGS__) /* * To specify a different default font cache limit, define this. If this is diff --git a/include/effects/SkMorphologyImageFilter.h b/include/effects/SkMorphologyImageFilter.h new file mode 100644 index 0000000..2297938 --- /dev/null +++ b/include/effects/SkMorphologyImageFilter.h @@ -0,0 +1,65 @@ +/* + * Copyright 2012 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#ifndef SkMorphologyImageFilter_DEFINED +#define SkMorphologyImageFilter_DEFINED + +#include "SkImageFilter.h" + +class SK_API SkMorphologyImageFilter : public SkImageFilter { +public: + explicit SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer); + SkMorphologyImageFilter(int radiusX, int radiusY); + +protected: + virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE; + SkISize radius() const { return fRadius; } + +private: + SkISize fRadius; + typedef SkImageFilter INHERITED; +}; + +class SK_API SkDilateImageFilter : public SkMorphologyImageFilter { +public: + SkDilateImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {} + explicit SkDilateImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + + virtual bool asADilate(SkISize* radius) const SK_OVERRIDE; + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { + return SkNEW_ARGS(SkDilateImageFilter, (buffer)); + } + virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } + SK_DECLARE_FLATTENABLE_REGISTRAR() + + typedef SkMorphologyImageFilter INHERITED; +}; + +class SK_API SkErodeImageFilter : public SkMorphologyImageFilter { +public: + SkErodeImageFilter(int radiusX, int radiusY) : INHERITED(radiusX, radiusY) {} + explicit SkErodeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {} + + virtual bool asAnErode(SkISize* radius) const SK_OVERRIDE; + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; + + static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { + return SkNEW_ARGS(SkErodeImageFilter, (buffer)); + } + virtual Factory getFactory() SK_OVERRIDE { return CreateProc; } + SK_DECLARE_FLATTENABLE_REGISTRAR() + +private: + typedef SkMorphologyImageFilter INHERITED; +}; + +#endif + diff --git a/include/effects/SkTableColorFilter.h b/include/effects/SkTableColorFilter.h index 0aefdbd..b442197 100644 --- a/include/effects/SkTableColorFilter.h +++ b/include/effects/SkTableColorFilter.h @@ -4,7 +4,7 @@ #include "SkColorFilter.h" -class SkTableColorFilter { +class SK_API SkTableColorFilter { public: /** * Create a table colorfilter, copying the table into the filter, and diff --git a/include/effects/SkTestImageFilters.h b/include/effects/SkTestImageFilters.h index db020ad..55522c1 100755 --- a/include/effects/SkTestImageFilters.h +++ b/include/effects/SkTestImageFilters.h @@ -3,6 +3,7 @@ #define _SkTestImageFilters_h #include "SkImageFilter.h" +#include "SkColorFilter.h" class SkOffsetImageFilter : public SkImageFilter { public: @@ -100,8 +101,6 @@ private: typedef SkImageFilter INHERITED; }; -class SkColorFilter; - class SkColorFilterImageFilter : public SkImageFilter { public: SkColorFilterImageFilter(SkColorFilter* cf) : fColorFilter(cf) { diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h index 72b9748..1dfe199 100644 --- a/include/gpu/GrConfig.h +++ b/include/gpu/GrConfig.h @@ -364,23 +364,6 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); } #define GR_GEOM_BUFFER_LOCK_THRESHOLD (1 << 15) #endif -/** - * Enables/disables use of offscreen AA - */ -#if !defined(GR_USE_OFFSCREEN_AA) - #define GR_USE_OFFSCREEN_AA 1 -#endif - -/** - * GR_MAX_OFFSCREEN_AA_SIZE controls the size at which offscreen AA will tile. - * Tiling saves GPU memory by limiting the size of the offscreen buffer. The - * max offscreen may be as large as (4*GR_MAX_OFFSCREEN_AA_SIZE)^2 pixels. - */ -#if !defined(GR_MAX_OFFSCREEN_AA_SIZE) - #define GR_MAX_OFFSCREEN_AA_SIZE 256 -#endif - - /////////////////////////////////////////////////////////////////////////////// // tail section: // diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 0308b5d..37160b1 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -75,6 +75,11 @@ public: */ void freeGpuResources(); + /** + * Returns the number of bytes of GPU memory hosted by the texture cache. + */ + size_t getGpuTextureCacheBytes() const; + /////////////////////////////////////////////////////////////////////////// // Textures @@ -82,7 +87,7 @@ public: * Token that refers to an entry in the texture cache. Returned by * functions that lock textures. Passed to unlockTexture. */ - class TextureCacheEntry { + class SK_API TextureCacheEntry { public: TextureCacheEntry() : fEntry(NULL) {} TextureCacheEntry(const TextureCacheEntry& e) : fEntry(e.fEntry) {} @@ -295,26 +300,6 @@ public: GrRenderTarget* createPlatformRenderTarget( const GrPlatformRenderTargetDesc& desc); - /** - * This interface is depracted and will be removed in a future revision. - * Callers should use createPlatformTexture or createPlatformRenderTarget - * instead. - * - * Wraps an existing 3D API surface in a GrObject. desc.fFlags determines - * the type of object returned. If kIsTexture is set the returned object - * will be a GrTexture*. Otherwise, it will be a GrRenderTarget*. If both - * are set the render target object is accessible by - * GrTexture::asRenderTarget(). - * - * GL: if the object is a texture Gr may change its GL texture parameters - * when it is drawn. - * - * @param desc description of the object to create. - * @return either a GrTexture* or GrRenderTarget* depending on desc. NULL - * on failure. - */ - GrResource* createPlatformSurface(const GrPlatformSurfaceDesc& desc); - /////////////////////////////////////////////////////////////////////////// // Matrix state @@ -577,31 +562,48 @@ public: * @param dst the render target to copy to. */ void copyTexture(GrTexture* src, GrRenderTarget* dst); + + /** + * Resolves a render target that has MSAA. The intermediate MSAA buffer is + * downsampled to the associated GrTexture (accessible via + * GrRenderTarget::asTexture()). Any pending draws to the render target will + * be executed before the resolve. + * + * This is only necessary when a client wants to access the object directly + * using the underlying graphics API. GrContext will detect when it must + * perform a resolve to a GrTexture used as the source of a draw or before + * reading pixels back from a GrTexture or GrRenderTarget. + */ + void resolveRenderTarget(GrRenderTarget* target); + /** - * Applies a 1D convolution kernel in the X direction to a rectangle of + * Applies a 1D convolution kernel in the given direction to a rectangle of * pixels from a given texture. * @param texture the texture to read from * @param rect the destination rectangle * @param kernel the convolution kernel (kernelWidth elements) * @param kernelWidth the width of the convolution kernel + * @param direction the direction in which to apply the kernel */ - void convolveInX(GrTexture* texture, - const SkRect& rect, - const float* kernel, - int kernelWidth); + void convolve(GrTexture* texture, + const SkRect& rect, + const float* kernel, + int kernelWidth, + GrSamplerState::FilterDirection direction); /** - * Applies a 1D convolution kernel in the Y direction to a rectangle of + * Applies a 1D morphology in the given direction to a rectangle of * pixels from a given texture. - * direction. * @param texture the texture to read from * @param rect the destination rectangle - * @param kernel the convolution kernel (kernelWidth elements) - * @param kernelWidth the width of the convolution kernel - */ - void convolveInY(GrTexture* texture, - const SkRect& rect, - const float* kernel, - int kernelWidth); + * @param radius the radius of the morphological operator + * @param filter the filter kernel (must be kDilate or kErode) + * @param direction the direction in which to apply the morphology + */ + void applyMorphology(GrTexture* texture, + const SkRect& rect, + int radius, + GrSamplerState::Filter filter, + GrSamplerState::FilterDirection direction); /////////////////////////////////////////////////////////////////////////// // Helpers @@ -670,7 +672,6 @@ private: GrIndexBuffer* fAAFillRectIndexBuffer; GrIndexBuffer* fAAStrokeRectIndexBuffer; - int fMaxOffscreenAASize; GrContext(GrGpu* gpu); @@ -699,47 +700,9 @@ private: GrPathRenderer* getPathRenderer(const GrPath& path, GrPathFill fill, + const GrDrawTarget* target, bool antiAlias); - struct OffscreenRecord; - - // determines whether offscreen AA should be applied - bool doOffscreenAA(GrDrawTarget* target, - bool isHairLines) const; - - // attempts to setup offscreen AA. All paint state must be transferred to - // target by the time this is called. - bool prepareForOffscreenAA(GrDrawTarget* target, - bool requireStencil, - const GrIRect& boundRect, - GrPathRenderer* pr, - OffscreenRecord* record); - - // sets up target to draw coverage to the supersampled render target - void setupOffscreenAAPass1(GrDrawTarget* target, - const GrIRect& boundRect, - int tileX, int tileY, - OffscreenRecord* record); - - // sets up target to sample coverage of supersampled render target back - // to the main render target using stage kOffscreenStage. - void doOffscreenAAPass2(GrDrawTarget* target, - const GrPaint& paint, - const GrIRect& boundRect, - int tileX, int tileY, - OffscreenRecord* record); - - // restored the draw target state and releases offscreen target to cache - void cleanupOffscreenAA(GrDrawTarget* target, - GrPathRenderer* pr, - OffscreenRecord* record); - - void convolve(GrTexture* texture, - const SkRect& rect, - float imageIncrement[2], - const float* kernel, - int kernelWidth); - /** * Flags to the internal read/write pixels funcs */ @@ -878,4 +841,3 @@ private: }; #endif - diff --git a/include/gpu/GrGLConfig_chrome.h b/include/gpu/GrGLConfig_chrome.h deleted file mode 100644 index ee3c991..0000000 --- a/include/gpu/GrGLConfig_chrome.h +++ /dev/null @@ -1,30 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#ifndef GrGLConfig_chrome_DEFINED -#define GrGLConfig_chrome_DEFINED - -// glGetError() forces a sync with gpu process on chrome -#define GR_GL_CHECK_ERROR_START 0 - -// ANGLE creates a temp VB for vertex attributes not specified per-vertex. -#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD - -// For RGBA teximage/readpixels ANGLE will sw-convert to/from BGRA. -#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW GR_WIN32_BUILD - -// ANGLE can go faster if the entire fbo is read rather than a subrect -#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL GR_WIN32_BUILD - -// cmd buffer allocates memory and memsets it to zero when it sees glBufferData -// with NULL. -#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0 - -// chrome uses this to set the context on each GL call. -#define GR_GL_PER_GL_FUNC_CALLBACK 1 - -#endif diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h index f1d74b2..9f220e0 100644 --- a/include/gpu/GrPaint.h +++ b/include/gpu/GrPaint.h @@ -36,6 +36,7 @@ public: bool fColorMatrixEnabled; GrColor fColor; + uint8_t fCoverage; GrColor fColorFilterColor; SkXfermode::Mode fColorFilterXfermode; @@ -126,6 +127,7 @@ public: fDither = paint.fDither; fColor = paint.fColor; + fCoverage = paint.fCoverage; fColorFilterColor = paint.fColorFilterColor; fColorFilterXfermode = paint.fColorFilterXfermode; @@ -161,6 +163,7 @@ public: this->resetBlend(); this->resetOptions(); this->resetColor(); + this->resetCoverage(); this->resetTextures(); this->resetColorFilter(); this->resetMasks(); @@ -242,6 +245,10 @@ private: fColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff); } + void resetCoverage() { + fCoverage = 0xff; + } + void resetTextures() { for (int i = 0; i < kMaxTextures; ++i) { this->setTexture(i, NULL); diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h index 13b2160..909adb3 100644 --- a/include/gpu/GrRenderTarget.h +++ b/include/gpu/GrRenderTarget.h @@ -112,6 +112,14 @@ public: */ const GrIRect& getResolveRect() const { return fResolveRect; } + /** + * If the render target is multisampled this will perform a multisample + * resolve. Any pending draws to the target are first flushed. This only + * applies to render targets that are associated with GrTextures. After the + * function returns the GrTexture will contain the resolved pixels. + */ + void resolve(); + // GrResource overrides virtual size_t sizeInBytes() const; diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h index 81dfdb3..50a6cc9 100644 --- a/include/gpu/GrSamplerState.h +++ b/include/gpu/GrSamplerState.h @@ -39,6 +39,14 @@ public: * Apply a separable convolution kernel. */ kConvolution_Filter, + /** + * Apply a dilate filter (max over a 1D radius). + */ + kDilate_Filter, + /** + * Apply an erode filter (min over a 1D radius). + */ + kErode_Filter, kDefault_Filter = kNearest_Filter }; @@ -87,6 +95,17 @@ public: }; /** + * For the filters which perform more than one texture sample (convolution, + * erode, dilate), this determines the direction in which the texture + * coordinates will be incremented. + */ + enum FilterDirection { + kX_FilterDirection, + kY_FilterDirection, + + kDefault_FilterDirection = kX_FilterDirection, + }; + /** * Default sampler state is set to clamp, use normal sampling mode, be * unfiltered, and use identity matrix. */ @@ -99,6 +118,7 @@ public: WrapMode getWrapX() const { return fWrapX; } WrapMode getWrapY() const { return fWrapY; } + FilterDirection getFilterDirection() const { return fFilterDirection; } SampleMode getSampleMode() const { return fSampleMode; } const GrMatrix& getMatrix() const { return fMatrix; } const GrRect& getTextureDomain() const { return fTextureDomain; } @@ -106,7 +126,6 @@ public: Filter getFilter() const { return fFilter; } int getKernelWidth() const { return fKernelWidth; } const float* getKernel() const { return fKernel; } - const float* getImageIncrement() const { return fImageIncrement; } bool swapsRAndB() const { return fSwapRAndB; } bool isGradient() const { @@ -118,6 +137,7 @@ public: void setWrapX(WrapMode mode) { fWrapX = mode; } void setWrapY(WrapMode mode) { fWrapY = mode; } void setSampleMode(SampleMode mode) { fSampleMode = mode; } + void setFilterDirection(FilterDirection mode) { fFilterDirection = mode; } /** * Access the sampler's matrix. See SampleMode for explanation of @@ -158,24 +178,29 @@ public: void reset(WrapMode wrapXAndY, Filter filter, + FilterDirection direction, const GrMatrix& matrix) { fWrapX = wrapXAndY; fWrapY = wrapXAndY; fSampleMode = kDefault_SampleMode; fFilter = filter; + fFilterDirection = direction; fMatrix = matrix; fTextureDomain.setEmpty(); fSwapRAndB = false; } + void reset(WrapMode wrapXAndY, Filter filter, const GrMatrix& matrix) { + this->reset(wrapXAndY, filter, kDefault_FilterDirection, matrix); + } void reset(WrapMode wrapXAndY, Filter filter) { - this->reset(wrapXAndY, filter, GrMatrix::I()); + this->reset(wrapXAndY, filter, kDefault_FilterDirection, GrMatrix::I()); } void reset(const GrMatrix& matrix) { - this->reset(kDefault_WrapMode, kDefault_Filter, matrix); + this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, matrix); } void reset() { - this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I()); + this->reset(kDefault_WrapMode, kDefault_Filter, kDefault_FilterDirection, GrMatrix::I()); } GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; } @@ -198,37 +223,37 @@ public: fRadial2PosRoot = posRoot; } - void setConvolutionParams(int kernelWidth, const float* kernel, float imageIncrement[2]) { + void setConvolutionParams(int kernelWidth, const float* kernel) { GrAssert(kernelWidth >= 0 && kernelWidth <= MAX_KERNEL_WIDTH); fKernelWidth = kernelWidth; if (NULL != kernel) { memcpy(fKernel, kernel, kernelWidth * sizeof(float)); } - if (NULL != imageIncrement) { - memcpy(fImageIncrement, imageIncrement, sizeof(fImageIncrement)); - } else { - memset(fImageIncrement, 0, sizeof(fImageIncrement)); - } + } + + void setMorphologyRadius(int radius) { + GrAssert(radius >= 0 && radius <= MAX_KERNEL_WIDTH); + fKernelWidth = radius; } private: - WrapMode fWrapX : 8; - WrapMode fWrapY : 8; - SampleMode fSampleMode : 8; - Filter fFilter : 8; - GrMatrix fMatrix; - bool fSwapRAndB; - GrRect fTextureDomain; + WrapMode fWrapX : 8; + WrapMode fWrapY : 8; + FilterDirection fFilterDirection : 8; + SampleMode fSampleMode : 8; + Filter fFilter : 8; + GrMatrix fMatrix; + bool fSwapRAndB; + GrRect fTextureDomain; // these are undefined unless fSampleMode == kRadial2_SampleMode - GrScalar fRadial2CenterX1; - GrScalar fRadial2Radius0; - SkBool8 fRadial2PosRoot; + GrScalar fRadial2CenterX1; + GrScalar fRadial2Radius0; + SkBool8 fRadial2PosRoot; // These are undefined unless fFilter == kConvolution_Filter - uint8_t fKernelWidth; - float fImageIncrement[2]; - float fKernel[MAX_KERNEL_WIDTH]; + uint8_t fKernelWidth; + float fKernel[MAX_KERNEL_WIDTH]; }; #endif diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h index 0bcab7d..f6809d6 100644 --- a/include/gpu/GrTypes.h +++ b/include/gpu/GrTypes.h @@ -301,6 +301,8 @@ enum GrPixelConfig { * Unpremultiplied. Byte order is b,g,r,a */ kBGRA_8888_UPM_GrPixelConfig, + + kGrPixelConfigCount }; // Aliases for pixel configs that match skia's byte order @@ -429,18 +431,10 @@ static inline bool GrPixelConfigIsAlphaOnly(GrPixelConfig config) { } /** - * Used to control the level of antialiasing available for a rendertarget. - * Anti-alias quality levels depend on the underlying API/GPU capabilities. - */ -enum GrAALevels { - kNone_GrAALevel, //<! No antialiasing available. - kLow_GrAALevel, //<! Low quality antialiased rendering. Actual - // interpretation is platform-dependent. - kMed_GrAALevel, //<! Medium quality antialiased rendering. Actual - // interpretation is platform-dependent. - kHigh_GrAALevel, //<! High quality antialiased rendering. Actual - // interpretation is platform-dependent. -}; + * DEPRECATED: This will be removed as soon as WebKit no longer references + * this (former) enum value. + */ +static const int kNone_GrAALevel = 0; /** * Optional bitfield flags that can be passed to createTexture. @@ -479,18 +473,31 @@ enum { */ struct GrTextureDesc { GrTextureFlags fFlags; //!< bitfield of TextureFlags - /** - * The level of antialiasing available for a rendertarget texture. Only used - * fFlags contains kRenderTarget_GrTextureFlag. - */ - GrAALevels fAALevel; int fWidth; //!< Width of the texture int fHeight; //!< Height of the texture + /** * Format of source data of the texture. Not guaraunteed to be the same as * internal format used by 3D API. */ GrPixelConfig fConfig; + + /** + * The number of samples per pixel or 0 to disable full scene AA. This only + * applies if the kRenderTarget_GrTextureFlagBit is set. The actual number + * of samples may not exactly match the request. The request will be rounded + * up to the next supported sample count, or down if it is larger than the + * max supportex count. + */ + union { + /** + * This field has two names for legacy reasons. Use the fSampleCnt name. + * fAALevel is deprecated and will be removed as soon as WebKit no + * longer uses it. + */ + int fSampleCnt; + int fAALevel; + }; }; /** @@ -593,24 +600,6 @@ static inline bool GrIsFillInverted(GrPathFill fill) { return gIsFillInverted[fill]; } -/** - * Hints provided about a path's convexity (or lack thereof). - */ -enum GrConvexHint { - kNone_ConvexHint, //<! No hint about convexity - // of the path - kConvex_ConvexHint, //<! Path is one convex piece - kNonOverlappingConvexPieces_ConvexHint, //<! Multiple convex pieces, - // pieces are known to be - // disjoint - kSameWindingConvexPieces_ConvexHint, //<! Multiple convex pieces, - // may or may not intersect, - // either all wind cw or all - // wind ccw. - kConcave_ConvexHint //<! Path is known to be - // concave -}; - /////////////////////////////////////////////////////////////////////////////// // opaque type for 3D API object handles @@ -702,133 +691,6 @@ struct GrPlatformRenderTargetDesc { GrPlatform3DObject fRenderTargetHandle; }; -/////////////////////////////////////////////////////////////////////////////// -// DEPRECATED. createPlatformSurface is replaced by createPlatformTexture -// and createPlatformRenderTarget. These enums and structs will be removed. - -enum GrPlatformSurfaceType { - /** - * Specifies that the object being created is a render target. - */ - kRenderTarget_GrPlatformSurfaceType, - /** - * Specifies that the object being created is a texture. - */ - kTexture_GrPlatformSurfaceType, - /** - * Specifies that the object being created is a texture and a render - * target. - */ - kTextureRenderTarget_GrPlatformSurfaceType, -}; - -enum GrPlatformRenderTargetFlags { - kNone_GrPlatformRenderTargetFlagBit = 0x0, - - /** - * Gives permission to Gr to perform the downsample-resolve of a - * multisampled render target. If this is not set then read pixel - * operations may fail. If the object is both a texture and render target - * then this *must* be set. Otherwise, if the client wants do its own - * resolves it must create separate GrRenderTarget and GrTexture objects - * and insert appropriate flushes and resolves betweeen data hazards. - * GrRenderTarget has a flagForResolve() - */ - kGrCanResolve_GrPlatformRenderTargetFlagBit = 0x2, -}; - -GR_MAKE_BITFIELD_OPS(GrPlatformRenderTargetFlags) - -struct GrPlatformSurfaceDesc { - GrPlatformSurfaceType fSurfaceType; // type of surface to create - /** - * Flags for kRenderTarget and kTextureRenderTarget surface types - */ - GrPlatformRenderTargetFlags fRenderTargetFlags; - - int fWidth; // width in pixels - int fHeight; // height in pixels - GrPixelConfig fConfig; // color format - /** - * Number of per sample stencil buffer. Only relevant if kIsRenderTarget is - * set in fFlags. - */ - int fStencilBits; - - /** - * Number of samples per-pixel. Only relevant if kIsRenderTarget is set in - * fFlags. - */ - int fSampleCnt; - - /** - * Texture object in 3D API. Only relevant if fSurfaceType is kTexture or - * kTextureRenderTarget. - * GL: this is a texture object (glGenTextures) - */ - GrPlatform3DObject fPlatformTexture; - /** - * Render target object in 3D API. Only relevant if fSurfaceType is - * kRenderTarget or kTextureRenderTarget - * GL: this is a FBO object (glGenFramebuffers) - */ - GrPlatform3DObject fPlatformRenderTarget; - /** - * 3D API object used as destination of resolve. Only relevant if - * fSurfaceType is kRenderTarget or kTextureRenderTarget and - * kGrCanResolve is set in fRenderTargetFlags. - * fFlags. - * GL: this is a FBO object (glGenFramebuffers) - */ - GrPlatform3DObject fPlatformResolveDestination; - - void reset() { memset(this, 0, sizeof(GrPlatformSurfaceDesc)); } -}; - -/** - * Example of how to wrap render-to-texture-with-MSAA GL objects with a GrPlatformSurace - * - * GLint colorBufferID; - * glGenRenderbuffers(1, &colorID); - * glBindRenderbuffer(GL_RENDERBUFFER, colorBufferID); - * glRenderbufferStorageMultisample(GL_RENDERBUFFER, S, GL_RGBA, W, H); - * - * GLint stencilBufferID; - * glGenRenderBuffers(1, &stencilBufferID); - * glBindRenderbuffer(GL_RENDERBUFFER, stencilBufferID); - * glRenderbufferStorageMultisample(GL_RENDERBUFFER, S, GL_STENCIL_INDEX8, W, H); - * - * GLint drawFBOID; - * glGenFramebuffers(1, &drawFBOID); - * glBindFramebuffer(GL_FRAMEBUFFER, drawFBOID); - * glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBufferID); - * glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilBufferID); - * - * GLint textureID; - * glGenTextures(1, &textureID); - * glBindTexture(GL_TEXTURE_2D, textureID); - * glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, H, ...); - * - * GLint readFBOID; - * glGenFramebuffers(1, &readFBOID); - * glBindFramebuffer(GL_FRAMEBUFFER, readFBOID); - * glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, 0); - * - * GrPlatformSurfaceDesc renderTargetTextureDesc; - * renderTargetTextureDesc.fSurfaceType = kTextureRenderTarget_GrPlatformSurfaceType; - * renderTargetTextureDesc.fRenderTargetFlags = kGrCanResolve_GrPlatformRenderTargetFlagBit; - * renderTargetTextureDesc.fWidth = W; - * renderTargetTextureDesc.fHeight = H; - * renderTargetTextureDesc.fConfig = kSkia8888_PM_GrPixelConfig - * renderTargetTextureDesc.fStencilBits = 8; - * renderTargetTextureDesc.fSampleCnt = S; - * renderTargetTextureDesc.fPlatformTexture = textureID; - * renderTargetTextureDesc.fPlatformRenderTarget = drawFBOID; - * renderTargetTextureDesc.fPlatformResolveDestination = readFBOID; - * - * GrTexture* texture = static_cast<GrTexture*>(grContext->createPlatrformSurface(renderTargetTextureDesc)); - */ - /////////////////////////////////////////////////////////////////////////////// diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h index 6c4285e..6663ed5 100644 --- a/include/gpu/SkGpuDevice.h +++ b/include/gpu/SkGpuDevice.h @@ -35,7 +35,7 @@ public: * internally. */ SkGpuDevice(GrContext*, SkBitmap::Config, - int width, int height, + int width, int height, SkDevice::Usage usage = SkDevice::kGeneral_Usage); /** @@ -102,7 +102,7 @@ public: const SkPaint&) SK_OVERRIDE; virtual bool filterTextFlags(const SkPaint&, TextFlags*) SK_OVERRIDE; - virtual void flush(); + virtual void flush(); /** * Make's this device's rendertarget current in the underlying 3D API. @@ -113,7 +113,7 @@ public: virtual bool filterImage(SkImageFilter*, const SkBitmap& src, const SkMatrix& ctm, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; - + protected: typedef GrContext::TextureCacheEntry TexCache; enum TexType { @@ -144,7 +144,7 @@ protected: TexCache fTex; }; friend class SkAutoTexCache; - + // overrides from SkDevice virtual bool onReadPixels(const SkBitmap& bitmap, int x, int y, @@ -170,8 +170,8 @@ private: // caller needs to null out GrPaint's texture if // non-textured drawing is desired. // Set constantColor to true if a constant color - // will be used. This is an optimization, and can - // always be set to false. constantColor should + // will be used. This is an optimization, and can + // always be set to false. constantColor should // never be true if justAlpha is true. bool skPaint2GrPaintNoShader(const SkPaint& skPaint, bool justAlpha, @@ -191,8 +191,8 @@ private: bool constantColor); // override from SkDevice - virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, + virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, + int width, int height, bool isOpaque, Usage usage); diff --git a/include/gpu/SkGrTexturePixelRef.h b/include/gpu/SkGrTexturePixelRef.h index 720f130..ab92eff 100644 --- a/include/gpu/SkGrTexturePixelRef.h +++ b/include/gpu/SkGrTexturePixelRef.h @@ -21,7 +21,7 @@ * Common baseclass that implements onLockPixels() by calling onReadPixels(). * Since it has a copy, it always returns false for onLockPixelsAreWritable(). */ -class SkROLockPixelsPixelRef : public SkPixelRef { +class SK_API SkROLockPixelsPixelRef : public SkPixelRef { public: SkROLockPixelsPixelRef(); virtual ~SkROLockPixelsPixelRef(); @@ -40,7 +40,7 @@ private: /** * PixelRef that wraps a GrTexture */ -class SkGrTexturePixelRef : public SkROLockPixelsPixelRef { +class SK_API SkGrTexturePixelRef : public SkROLockPixelsPixelRef { public: SkGrTexturePixelRef(GrTexture*); virtual ~SkGrTexturePixelRef(); @@ -63,7 +63,7 @@ private: /** * PixelRef that wraps a GrRenderTarget */ -class SkGrRenderTargetPixelRef : public SkROLockPixelsPixelRef { +class SK_API SkGrRenderTargetPixelRef : public SkROLockPixelsPixelRef { public: SkGrRenderTargetPixelRef(GrRenderTarget* rt); virtual ~SkGrRenderTargetPixelRef(); diff --git a/include/gpu/GrGLConfig.h b/include/gpu/gl/GrGLConfig.h index c9aaec5..806f055 100644 --- a/include/gpu/GrGLConfig.h +++ b/include/gpu/gl/GrGLConfig.h @@ -86,48 +86,98 @@ * glReadPixels to read the entire framebuffer is faster than calling it with * the same sized rectangle but with a framebuffer bound that is larger than * the rectangle read. + * + * GR_GL_CHECK_ALLOC_WITH_GET_ERROR: If set to 1 this will then glTexImage, + * glBufferData, glRenderbufferStorage, etc will be checked for errors. This + * amounts to ensuring the error is GL_NO_ERROR, calling the allocating + * function, and then checking that the error is still GL_NO_ERROR. When the + * value is 0 we will assume no error was generated without checking. + * + * GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT: We will normally check the FBO status + * every time we bind a texture or renderbuffer to an FBO. However, in some + * environments CheckFrameBufferStatus is very expensive. If this is set we will + * check the first time we use a color format or a combination of color / + * stencil formats as attachments. If the FBO is complete we will assume + * subsequent attachments with the same formats are complete as well. */ #if !defined(GR_GL_LOG_CALLS) - #define GR_GL_LOG_CALLS GR_DEBUG + #define GR_GL_LOG_CALLS GR_DEBUG #endif #if !defined(GR_GL_LOG_CALLS_START) - #define GR_GL_LOG_CALLS_START 0 + #define GR_GL_LOG_CALLS_START 0 #endif #if !defined(GR_GL_CHECK_ERROR) - #define GR_GL_CHECK_ERROR GR_DEBUG + #define GR_GL_CHECK_ERROR GR_DEBUG #endif #if !defined(GR_GL_CHECK_ERROR_START) - #define GR_GL_CHECK_ERROR_START 1 + #define GR_GL_CHECK_ERROR_START 1 #endif #if !defined(GR_GL_NO_CONSTANT_ATTRIBUTES) - #define GR_GL_NO_CONSTANT_ATTRIBUTES 0 + #define GR_GL_NO_CONSTANT_ATTRIBUTES 0 #endif #if !defined(GR_GL_ATTRIBUTE_MATRICES) - #define GR_GL_ATTRIBUTE_MATRICES 0 + #define GR_GL_ATTRIBUTE_MATRICES 0 #endif #if !defined(GR_GL_USE_BUFFER_DATA_NULL_HINT) - #define GR_GL_USE_BUFFER_DATA_NULL_HINT 1 + #define GR_GL_USE_BUFFER_DATA_NULL_HINT 1 #endif #if !defined(GR_GL_PER_GL_FUNC_CALLBACK) - #define GR_GL_PER_GL_FUNC_CALLBACK 0 + #define GR_GL_PER_GL_FUNC_CALLBACK 0 #endif #if !defined(GR_GL_RGBA_8888_PIXEL_OPS_SLOW) - #define GR_GL_RGBA_8888_PIXEL_OPS_SLOW 0 + #define GR_GL_RGBA_8888_PIXEL_OPS_SLOW 0 #endif #if !defined(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL) - #define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0 + #define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0 +#endif + +#if !defined(GR_GL_CHECK_ALLOC_WITH_GET_ERROR) + #define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 1 #endif +#if !defined(GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT) + #define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 0 +#endif + +/** + * There is a strange bug that occurs on Macs with NVIDIA GPUs. We don't + * fully understand it. When (element) array buffers are continually + * respecified using glBufferData performance can fall off of a cliff. The + * driver winds up performing many DMA mapping / unmappings and chews up ~50% of + * the core. However, it has been observed that occaisonally respecifiying the + * buffer using glBufferData and then writing data using glBufferSubData + * prevents the bad behavior. + * + * There is a lot of uncertainty around this issue. In Chrome backgrounding + * the tab somehow initiates this behavior and we don't know what the connection + * is. Another observation is that Chrome's cmd buffer server will actually + * create a buffer full of zeros when it sees a NULL data param (for security + * reasons). If this is disabled and NULL is actually passed all the way to the + * driver then the workaround doesn't help. + * + * The issue is tracked at: + * http://code.google.com/p/chromium/issues/detail?id=114865 + * + * When the workaround is enabled we will use the glBufferData / glBufferSubData + * trick every 128 array buffer uploads. + * + * Hopefully we will understand this better and have a cleaner fix or get a + * OS/driver level fix. + */ +#define GR_GL_MAC_BUFFER_OBJECT_PERFOMANCE_WORKAROUND \ + (GR_MAC_BUILD && \ + !GR_GL_USE_BUFFER_DATA_NULL_HINT) + #if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES) #error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES" #endif diff --git a/include/gpu/gl/GrGLConfig_chrome.h b/include/gpu/gl/GrGLConfig_chrome.h new file mode 100644 index 0000000..50ea34c --- /dev/null +++ b/include/gpu/gl/GrGLConfig_chrome.h @@ -0,0 +1,37 @@ + +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#ifndef GrGLConfig_chrome_DEFINED +#define GrGLConfig_chrome_DEFINED + +// glGetError() forces a sync with gpu process on chrome +#define GR_GL_CHECK_ERROR_START 0 + +// ANGLE creates a temp VB for vertex attributes not specified per-vertex. +#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD + +// For RGBA teximage/readpixels ANGLE will sw-convert to/from BGRA. +#define GR_GL_RGBA_8888_PIXEL_OPS_SLOW GR_WIN32_BUILD + +// ANGLE can go faster if the entire fbo is read rather than a subrect +#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL GR_WIN32_BUILD + +// cmd buffer allocates memory and memsets it to zero when it sees glBufferData +// with NULL. +#define GR_GL_USE_BUFFER_DATA_NULL_HINT 0 + +// chrome uses this to set the context on each GL call. +#define GR_GL_PER_GL_FUNC_CALLBACK 1 + +// Check error is even more expensive in chrome (cmd buffer flush). The +// compositor also doesn't check its allocations. +#define GR_GL_CHECK_ALLOC_WITH_GET_ERROR 0 + +// CheckFramebufferStatus in chrome synchronizes the gpu and renderer processes. +#define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 1 + +#endif diff --git a/include/gpu/GrGLDefines.h b/include/gpu/gl/GrGLDefines.h index e66eec4..e66eec4 100644 --- a/include/gpu/GrGLDefines.h +++ b/include/gpu/gl/GrGLDefines.h diff --git a/include/gpu/GrGLInterface.h b/include/gpu/gl/GrGLInterface.h index 716cff9..968afab 100644 --- a/include/gpu/GrGLInterface.h +++ b/include/gpu/gl/GrGLInterface.h @@ -21,6 +21,23 @@ //////////////////////////////////////////////////////////////////////////////// /** + * Classifies GL contexts (currently as Desktop vs. ES2). This is a bitfield. + * A GrGLInterface (defined below) may support multiple bindings. + */ +enum GrGLBinding { + kNone_GrGLBinding = 0x0, + + kDesktop_GrGLBinding = 0x01, + kES2_GrGLBinding = 0x02, + + // for iteration of GrGLBindings + kFirstGrGLBinding = kDesktop_GrGLBinding, + kLastGrGLBinding = kES2_GrGLBinding +}; + +//////////////////////////////////////////////////////////////////////////////// + +/** * Helpers for glGetString() */ @@ -34,11 +51,13 @@ typedef uint32_t GrGLSLVersion; // these variants assume caller already has a string from glGetString() GrGLVersion GrGLGetVersionFromString(const char* versionString); +GrGLBinding GrGLGetBindingInUseFromString(const char* versionString); GrGLSLVersion GrGLGetGLSLVersionFromString(const char* versionString); bool GrGLHasExtensionFromString(const char* ext, const char* extensionString); // these variants call glGetString() bool GrGLHasExtension(const GrGLInterface*, const char* ext); +GrGLBinding GrGLGetBindingInUse(const GrGLInterface*); GrGLVersion GrGLGetVersion(const GrGLInterface*); GrGLSLVersion GrGLGetGLSLVersion(const GrGLInterface*); @@ -109,11 +128,6 @@ typedef void GrGLvoid; typedef long GrGLintptr; typedef long GrGLsizeiptr; -enum GrGLBinding { - kDesktop_GrGLBinding = 0x01, - kES2_GrGLBinding = 0x02 -}; - extern "C" { typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLActiveTextureProc)(GrGLenum texture); typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLAttachShaderProc)(GrGLuint program, GrGLuint shader); @@ -267,13 +281,10 @@ struct GR_API GrGLInterface : public GrRefCnt { GrGLInterface(); - bool validate() const; - bool supportsDesktop() const { - return 0 != (kDesktop_GrGLBinding & fBindingsExported); - } - bool supportsES2() const { - return 0 != (kES2_GrGLBinding & fBindingsExported); - } + // Validates that the GrGLInterface supports a binding. This means that + // the GrGLinterface advertises the binding in fBindingsExported and all + // the necessary function pointers have been initialized. + bool validate(GrGLBinding binding) const; // Indicator variable specifying the type of GL implementation // exported: GLES{1|2} or Desktop. diff --git a/include/gpu/SkGLContext.h b/include/gpu/gl/SkGLContext.h index f92a770..542d1bb 100644 --- a/include/gpu/SkGLContext.h +++ b/include/gpu/gl/SkGLContext.h @@ -9,6 +9,7 @@ #define SkGLContext_DEFINED #include "GrGLInterface.h" +#include "SkString.h" /** * Create an offscreen opengl context with an RGBA8 / 8bit stencil FBO. @@ -31,6 +32,8 @@ public: virtual void makeCurrent() const = 0; + bool hasExtension(const char* extensionName) const; + protected: /** * Subclass implements this to make a GL context. The returned GrGLInterface @@ -46,6 +49,7 @@ protected: virtual void destroyGLContext() = 0; private: + SkString fExtensionString; GrGLuint fFBO; const GrGLInterface* fGL; }; diff --git a/include/gpu/SkMesaGLContext.h b/include/gpu/gl/SkMesaGLContext.h index 5c329ff..5c329ff 100644 --- a/include/gpu/SkMesaGLContext.h +++ b/include/gpu/gl/SkMesaGLContext.h diff --git a/include/gpu/SkNativeGLContext.h b/include/gpu/gl/SkNativeGLContext.h index 36461ba..36461ba 100644 --- a/include/gpu/SkNativeGLContext.h +++ b/include/gpu/gl/SkNativeGLContext.h diff --git a/include/gpu/SkNullGLContext.h b/include/gpu/gl/SkNullGLContext.h index 9e16cee..9e16cee 100644 --- a/include/gpu/SkNullGLContext.h +++ b/include/gpu/gl/SkNullGLContext.h diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h index 4551149..9d6b54c 100644 --- a/include/pdf/SkPDFDevice.h +++ b/include/pdf/SkPDFDevice.h @@ -156,7 +156,7 @@ public: const SkPDFGlyphSetMap& getFontGlyphUsage() const { return *(fFontGlyphUsage.get()); } - + protected: virtual bool onReadPixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888) SK_OVERRIDE; diff --git a/include/pdf/SkPDFFont.h b/include/pdf/SkPDFFont.h index b884017..2ebdec7 100644 --- a/include/pdf/SkPDFFont.h +++ b/include/pdf/SkPDFFont.h @@ -196,7 +196,7 @@ private: // This should be made a hash table if performance is a problem. static SkTDArray<FontRec>& CanonicalFonts(); - static SkMutex& CanonicalFontsMutex(); + static SkBaseMutex& CanonicalFontsMutex(); }; #endif diff --git a/include/pdf/SkPDFGraphicState.h b/include/pdf/SkPDFGraphicState.h index 9420405..af01737 100644 --- a/include/pdf/SkPDFGraphicState.h +++ b/include/pdf/SkPDFGraphicState.h @@ -86,7 +86,7 @@ private: // This should be made a hash table if performance is a problem. static SkTDArray<GSCanonicalEntry>& CanonicalPaints(); - static SkMutex& CanonicalPaintsMutex(); + static SkBaseMutex& CanonicalPaintsMutex(); SkPDFGraphicState(); explicit SkPDFGraphicState(const SkPaint& paint); diff --git a/include/pdf/SkPDFShader.h b/include/pdf/SkPDFShader.h index 6b6ae03..439d83b 100644 --- a/include/pdf/SkPDFShader.h +++ b/include/pdf/SkPDFShader.h @@ -56,7 +56,7 @@ protected: }; // This should be made a hash table if performance is a problem. static SkTDArray<ShaderCanonicalEntry>& CanonicalShaders(); - static SkMutex& CanonicalShadersMutex(); + static SkBaseMutex& CanonicalShadersMutex(); static void RemoveShader(SkPDFObject* shader); SkPDFShader(); diff --git a/include/utils/SkDeferredCanvas.h b/include/utils/SkDeferredCanvas.h new file mode 100644 index 0000000..87797ac --- /dev/null +++ b/include/utils/SkDeferredCanvas.h @@ -0,0 +1,302 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkDeferredCanvas_DEFINED +#define SkDeferredCanvas_DEFINED + +#include "SkCanvas.h" +#include "SkDevice.h" +#include "SkPicture.h" +#include "SkPixelRef.h" + +/** \class SkDeferredCanvas + Subclass of SkCanvas that encapsulates an SkPicture for deferred drawing. + The main difference between this class and SkPictureRecord (the canvas + provided by SkPicture) is that this is a full drop-in replacement for + SkCanvas, while SkPictureRecord only supports draw operations. + SkDeferredCanvas will transparently trigger the flushing of deferred + draw operations when an attempt is made to access the pixel data. +*/ +class SK_API SkDeferredCanvas : public SkCanvas { +public: + class DeviceContext; + + SkDeferredCanvas(); + + /** Construct a canvas with the specified device to draw into. + Equivalent to calling default constructor, then setDevice. + @param device Specifies a device for the canvas to draw into. + */ + explicit SkDeferredCanvas(SkDevice* device); + + /** Construct a canvas with the specified device to draw into, and + * a device context. Equivalent to calling default constructor, then + * setDevice. + * @param device Specifies a device for the canvas to draw into. + * @param deviceContext interface for the device's the graphics context + */ + explicit SkDeferredCanvas(SkDevice* device, DeviceContext* deviceContext); + + virtual ~SkDeferredCanvas(); + + /** + * Specify a device to be used by this canvas. Calling setDevice will + * release the previously set device, if any. + * + * @param device The device that the canvas will raw into + * @return The device argument, for convenience. + */ + virtual SkDevice* setDevice(SkDevice* device); + + /** + * Specify a deviceContext to be used by this canvas. Calling + * setDeviceContext will release the previously set deviceContext, if any. + * A deviceContext must be specified if the device uses a graphics context + * that requires some form of state initialization prior to drawing + * and/or explicit flushing to synchronize the execution of rendering + * operations. + * Note: Must be called after the device is set with setDevice. + * + * @deviceContext interface for the device's the graphics context + * @return The deviceContext argument, for convenience. + */ + DeviceContext* setDeviceContext(DeviceContext* deviceContext); + + /** + * Enable or disable deferred drawing. When deferral is disabled, + * pending draw operations are immediately flushed and from then on, + * the SkDeferredCanvas behaves just like a regular SkCanvas. + * This method must not be called while the save/restore stack is in use. + * @param deferred true/false + */ + void setDeferredDrawing(bool deferred); + + // Overrides of the SkCanvas interface + virtual int save(SaveFlags flags) SK_OVERRIDE; + virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) SK_OVERRIDE; + virtual void restore() SK_OVERRIDE; + virtual bool isDrawingToLayer() const SK_OVERRIDE; + virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; + virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; + virtual bool rotate(SkScalar degrees) SK_OVERRIDE; + virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; + virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; + virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; + virtual bool clipRect(const SkRect& rect, SkRegion::Op op, + bool doAntiAlias) SK_OVERRIDE; + virtual bool clipPath(const SkPath& path, SkRegion::Op op, + bool doAntiAlias) SK_OVERRIDE; + virtual bool clipRegion(const SkRegion& deviceRgn, + SkRegion::Op op) SK_OVERRIDE; + virtual void clear(SkColor) SK_OVERRIDE; + virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; + virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], + const SkPaint& paint) SK_OVERRIDE; + virtual void drawRect(const SkRect& rect, const SkPaint& paint) + SK_OVERRIDE; + virtual void drawPath(const SkPath& path, const SkPaint& paint) + SK_OVERRIDE; + virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, + SkScalar top, const SkPaint* paint) + SK_OVERRIDE; + virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, + const SkRect& dst, const SkPaint* paint) + SK_OVERRIDE; + + virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, + const SkPaint* paint) SK_OVERRIDE; + virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, + const SkRect& dst, const SkPaint* paint) + SK_OVERRIDE; + virtual void drawSprite(const SkBitmap& bitmap, int left, int top, + const SkPaint* paint) SK_OVERRIDE; + virtual void drawText(const void* text, size_t byteLength, SkScalar x, + SkScalar y, const SkPaint& paint) SK_OVERRIDE; + virtual void drawPosText(const void* text, size_t byteLength, + const SkPoint pos[], const SkPaint& paint) + SK_OVERRIDE; + virtual void drawPosTextH(const void* text, size_t byteLength, + const SkScalar xpos[], SkScalar constY, + const SkPaint& paint) SK_OVERRIDE; + virtual void drawTextOnPath(const void* text, size_t byteLength, + const SkPath& path, const SkMatrix* matrix, + const SkPaint& paint) SK_OVERRIDE; + virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; + virtual void drawVertices(VertexMode vmode, int vertexCount, + const SkPoint vertices[], const SkPoint texs[], + const SkColor colors[], SkXfermode* xmode, + const uint16_t indices[], int indexCount, + const SkPaint& paint) SK_OVERRIDE; + virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; + virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; + +private: + void flushIfNeeded(const SkBitmap& bitmap); + +public: + class DeviceContext : public SkRefCnt { + public: + virtual void prepareForDraw() {} + }; + +public: + class DeferredDevice : public SkDevice { + public: + /** + * Constructor + * @param immediateDevice device to be drawn to when flushing + * deferred operations + * @param deviceContext callback interface for managing graphics + * context state, can be NULL. + */ + DeferredDevice(SkDevice* immediateDevice, + DeviceContext* deviceContext = NULL); + ~DeferredDevice(); + + /** + * Sets the device context to be use with the device. + * @param deviceContext callback interface for managing graphics + * context state, can be NULL. + */ + void setDeviceContext(DeviceContext* deviceContext); + + /** + * Returns the recording canvas. + */ + SkCanvas* recordingCanvas() const {return fRecordingCanvas;} + + /** + * Returns the immediate (non deferred) canvas. + */ + SkCanvas* immediateCanvas() const {return fImmediateCanvas;} + + /** + * Returns the immediate (non deferred) device. + */ + SkDevice* immediateDevice() const {return fImmediateDevice;} + + /** + * Returns true if an opaque draw operation covering the entire canvas + * was performed since the last call to isFreshFrame(). + */ + bool isFreshFrame(); + + void flushPending(); + void contentsCleared(); + void flushIfNeeded(const SkBitmap& bitmap); + + virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; + virtual int width() const SK_OVERRIDE; + virtual int height() const SK_OVERRIDE; + virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE; + + virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config, + int width, int height, + bool isOpaque, + Usage usage) SK_OVERRIDE; + + virtual void writePixels(const SkBitmap& bitmap, int x, int y, + SkCanvas::Config8888 config8888) SK_OVERRIDE; + + protected: + virtual const SkBitmap& onAccessBitmap(SkBitmap*) SK_OVERRIDE; + virtual bool onReadPixels(const SkBitmap& bitmap, + int x, int y, + SkCanvas::Config8888 config8888) SK_OVERRIDE; + + // The following methods are no-ops on a deferred device + virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) + SK_OVERRIDE + {return false;} + virtual void setMatrixClip(const SkMatrix&, const SkRegion&, + const SkClipStack&) SK_OVERRIDE + {} + virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&, + const SkClipStack&) SK_OVERRIDE + {} + + // None of the following drawing methods should ever get called on the + // deferred device + virtual void clear(SkColor color) + {SkASSERT(0);} + virtual void drawPaint(const SkDraw&, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, + size_t count, const SkPoint[], + const SkPaint& paint) + {SkASSERT(0);} + virtual void drawRect(const SkDraw&, const SkRect& r, + const SkPaint& paint) + {SkASSERT(0);} + virtual void drawPath(const SkDraw&, const SkPath& path, + const SkPaint& paint, + const SkMatrix* prePathMatrix = NULL, + bool pathIsMutable = false) + {SkASSERT(0);} + virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, + const SkIRect* srcRectOrNull, + const SkMatrix& matrix, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, + int x, int y, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawText(const SkDraw&, const void* text, size_t len, + SkScalar x, SkScalar y, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawPosText(const SkDraw&, const void* text, size_t len, + const SkScalar pos[], SkScalar constY, + int scalarsPerPos, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawTextOnPath(const SkDraw&, const void* text, + size_t len, const SkPath& path, + const SkMatrix* matrix, + const SkPaint& paint) + {SkASSERT(0);} + virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, + size_t len, const SkPoint pos[], + const SkPaint& paint, + const SkPath& path, + const SkMatrix* matrix) + {SkASSERT(0);} + virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, + int vertexCount, const SkPoint verts[], + const SkPoint texs[], const SkColor colors[], + SkXfermode* xmode, const uint16_t indices[], + int indexCount, const SkPaint& paint) + {SkASSERT(0);} + virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y, + const SkPaint&) + {SkASSERT(0);} + private: + virtual void flush(); + + SkPicture fPicture; + SkDevice* fImmediateDevice; + SkCanvas* fImmediateCanvas; + SkCanvas* fRecordingCanvas; + DeviceContext* fDeviceContext; + bool fFreshFrame; + }; + + DeferredDevice* getDeferredDevice() const; + +protected: + virtual SkCanvas* canvasForDrawIter(); + +private: + SkCanvas* drawingCanvas() const; + bool isFullFrame(const SkRect*, const SkPaint*) const; + void validate() const; + void init(); + bool fDeferredDrawing; + + typedef SkCanvas INHERITED; +}; + + +#endif diff --git a/include/utils/SkDumpCanvas.h b/include/utils/SkDumpCanvas.h index 5bfd6f6..de2af04 100644 --- a/include/utils/SkDumpCanvas.h +++ b/include/utils/SkDumpCanvas.h @@ -12,7 +12,7 @@ /** This class overrides all the draw methods on SkCanvas, and formats them as text, and then sends that to a Dumper helper object. - + Typical use might be to dump a display list to a log file to see what is being drawn. */ @@ -22,17 +22,17 @@ public: explicit SkDumpCanvas(Dumper* = 0); virtual ~SkDumpCanvas(); - + enum Verb { kNULL_Verb, kSave_Verb, kRestore_Verb, - + kMatrix_Verb, - + kClip_Verb, - + kDrawPaint_Verb, kDrawPoints_Verb, kDrawRect_Verb, @@ -43,7 +43,7 @@ public: kDrawVertices_Verb, kDrawData_Verb }; - + /** Subclasses of this are installed on the DumpCanvas, and then called for each drawing command. */ @@ -52,12 +52,12 @@ public: virtual void dump(SkDumpCanvas*, SkDumpCanvas::Verb, const char str[], const SkPaint*) = 0; }; - + Dumper* getDumper() const { return fDumper; } void setDumper(Dumper*); - + int getNestLevel() const { return fNestLevel; } - + virtual int save(SaveFlags) SK_OVERRIDE; virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags) SK_OVERRIDE; @@ -69,7 +69,7 @@ public: virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - + virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; virtual bool clipRegion(const SkRegion& deviceRgn, @@ -109,7 +109,7 @@ public: private: Dumper* fDumper; int fNestLevel; // for nesting recursive elements like pictures - + void dump(Verb, const SkPaint*, const char format[], ...); typedef SkCanvas INHERITED; @@ -121,16 +121,16 @@ private: class SkFormatDumper : public SkDumpCanvas::Dumper { public: SkFormatDumper(void (*)(const char text[], void* refcon), void* refcon); - + // override from baseclass that does the formatting, and in turn calls // the function pointer that was passed to the constructor virtual void dump(SkDumpCanvas*, SkDumpCanvas::Verb, const char str[], const SkPaint*) SK_OVERRIDE; - + private: void (*fProc)(const char*, void*); void* fRefcon; - + typedef SkDumpCanvas::Dumper INHERITED; }; diff --git a/include/utils/SkNWayCanvas.h b/include/utils/SkNWayCanvas.h index 4e39c6b..69c1fcf 100644 --- a/include/utils/SkNWayCanvas.h +++ b/include/utils/SkNWayCanvas.h @@ -15,7 +15,7 @@ class SkNWayCanvas : public SkCanvas { public: SkNWayCanvas(); virtual ~SkNWayCanvas(); - + void addCanvas(SkCanvas*); void removeCanvas(SkCanvas*); void removeAll(); @@ -70,10 +70,10 @@ public: virtual SkBounder* setBounder(SkBounder*) SK_OVERRIDE; virtual SkDrawFilter* setDrawFilter(SkDrawFilter*) SK_OVERRIDE; - + private: SkTDArray<SkCanvas*> fList; - + class Iter; typedef SkCanvas INHERITED; diff --git a/include/utils/SkProxyCanvas.h b/include/utils/SkProxyCanvas.h index e96b9b2..720436b 100644 --- a/include/utils/SkProxyCanvas.h +++ b/include/utils/SkProxyCanvas.h @@ -13,7 +13,7 @@ /** This class overrides all virtual methods on SkCanvas, and redirects them to a "proxy", another SkCanvas instance. It can be the basis for intercepting (and possibly modifying) calls to a canvas. - + There must be a proxy installed before the proxycanvas can be used (i.e. before its virtual methods can be called). */ @@ -22,10 +22,10 @@ public: SkProxyCanvas() : fProxy(NULL) {} SkProxyCanvas(SkCanvas* proxy); virtual ~SkProxyCanvas(); - + SkCanvas* getProxy() const { return fProxy; } void setProxy(SkCanvas* proxy); - + virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE; virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE; @@ -37,7 +37,7 @@ public: virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - + virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; virtual bool clipRegion(const SkRegion& deviceRgn, @@ -79,7 +79,7 @@ public: private: SkCanvas* fProxy; - + typedef SkCanvas INHERITED; }; diff --git a/include/utils/mac/SkCGUtils.h b/include/utils/mac/SkCGUtils.h index 055e24c..46f8996 100644 --- a/include/utils/mac/SkCGUtils.h +++ b/include/utils/mac/SkCGUtils.h @@ -25,8 +25,8 @@ class SkStream; * Create an imageref from the specified bitmap using the specified colorspace. * If space is NULL, then CGColorSpaceCreateDeviceRGB() is used. */ -CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, - CGColorSpaceRef space); +SK_API CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, + CGColorSpaceRef space); /** * Create an imageref from the specified bitmap using the colorspace returned @@ -46,4 +46,19 @@ void SkCGDrawBitmap(CGContextRef, const SkBitmap&, float x, float y); bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output); +/** + * Return a provider that wraps the specified stream. It will become an + * owner of the stream, so the caller must still manage its ownership. + * + * To hand-off ownership of the stream to the provider, the caller must do + * something like the following: + * + * SkStream* stream = new ...; + * CGDataProviderRef provider = SkStreamToDataProvider(stream); + * stream->unref(); + * + * Now when the provider is finally deleted, it will delete the stream. + */ +CGDataProviderRef SkCreateDataProviderFromStream(SkStream*); + #endif |