Bug 716415 - Update Skia to svn revision 2980. r=jrmuizel

This commit is contained in:
Matt Woodrow 2012-01-19 17:48:34 +13:00
parent a3acc6b329
commit aa73b35eee
273 changed files with 13876 additions and 5766 deletions

View File

@ -2,4 +2,4 @@ The source from this directory was copied from the skia subversion trunk
using the update.sh script. The changes made were those applied by update.sh,
the addition/update of Makefile.in files for the Mozilla build system.
The subversion revision used was r2232.
The subversion revision used was r2980.

View File

@ -93,18 +93,18 @@
//#define SkLONGLONG int64_t
/* Some envorinments do not suport writable globals (eek!). If yours does not,
define this flag.
*/
//#define SK_USE_RUNTIME_GLOBALS
/* To write debug messages to a console, skia will call SkDebugf(...) following
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__)
/*
* To specify a different default font cache limit, define this. If this is
* undefined, skia will use a built-in value.
*/
//#define SK_DEFAULT_FONT_CACHE_LIMIT (1024 * 1024)
/* If defined, use CoreText instead of ATSUI on OS X.
*/
//#define SK_USE_MAC_CORE_TEXT
@ -145,8 +145,6 @@
//#define SK_SUPPORT_UNITTEST
#endif
#define SK_DISABLE_DITHER_32BIT_GRADIENT
/* If your system embeds skia and has complex event logging, define this
symbol to name a file that maps the following macros to your system's
equivalents:
@ -168,8 +166,4 @@
#define SK_A32_SHIFT 24
#endif
#ifdef SK_BUILD_FOR_WIN32
#define SK_IGNORE_STDINT_DOT_H
#endif
#endif

View File

@ -158,6 +158,19 @@ public:
*/
Sk64 getSafeSize64() const ;
/** Returns true if this bitmap is marked as immutable, meaning that the
contents of its pixels will not change for the lifetime of the bitmap.
*/
bool isImmutable() const;
/** Marks this bitmap as immutable, meaning that the contents of its
pixels will not change for the lifetime of the bitmap and of the
underlying pixelref. This state can be set, but it cannot be
cleared once it is set. This state propagates to all other bitmaps
that share the same pixelref.
*/
void setImmutable();
/** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
*/
bool isOpaque() const;
@ -225,12 +238,11 @@ public:
/** Copies the bitmap's pixels to the location pointed at by dst and returns
true if possible, returns false otherwise.
In the event that the bitmap's stride is equal to dstRowBytes, and if
it is greater than strictly required by the bitmap's current config
(this may happen if the bitmap is an extracted subset of another), then
this function will copy bytes past the eand of each row, excluding the
last row. No copies are made outside of the declared size of dst,
however.
In the case when the dstRowBytes matches the bitmap's rowBytes, the copy
may be made faster by copying over the dst's per-row padding (for all
rows but the last). By setting preserveDstPad to true the caller can
disable this optimization and ensure that pixels in the padding are not
overwritten.
Always returns false for RLE formats.
@ -239,27 +251,12 @@ public:
pixels using indicated stride.
@param dstRowBytes Width of each line in the buffer. If -1, uses
bitmap's internal stride.
@param preserveDstPad Must we preserve padding in the dst
*/
bool copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes = -1)
bool copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes = -1,
bool preserveDstPad = false)
const;
/** Copies the pixels at location src to the bitmap's pixel buffer.
Returns true if copy if possible (bitmap buffer is large enough),
false otherwise.
Like copyPixelsTo, this function may write values beyond the end of
each row, although never outside the defined buffer.
Always returns false for RLE formats.
@param src Location of the source buffer.
@param srcSize Height of source buffer in pixels.
@param srcRowBytes Width of each line in the buffer. If -1, uses i
bitmap's internal stride.
*/
bool copyPixelsFrom(const void* const src, size_t srcSize,
int srcRowBytes = -1);
/** Use the standard HeapAllocator to create the pixelref that manages the
pixel memory. It will be sized based on the current width/height/config.
If this is called multiple times, a new pixelref object will be created
@ -478,19 +475,29 @@ public:
*/
bool extractSubset(SkBitmap* dst, const SkIRect& subset) const;
/** Makes a deep copy of this bitmap, respecting the requested config.
Returns false if either there is an error (i.e. the src does not have
pixels) or the request cannot be satisfied (e.g. the src has per-pixel
alpha, and the requested config does not support alpha).
@param dst The bitmap to be sized and allocated
@param c The desired config for dst
@param allocator Allocator used to allocate the pixelref for the dst
bitmap. If this is null, the standard HeapAllocator
will be used.
@return true if the copy could be made.
/** Makes a deep copy of this bitmap, respecting the requested config,
* and allocating the dst pixels on the cpu.
* Returns false if either there is an error (i.e. the src does not have
* pixels) or the request cannot be satisfied (e.g. the src has per-pixel
* alpha, and the requested config does not support alpha).
* @param dst The bitmap to be sized and allocated
* @param c The desired config for dst
* @param allocator Allocator used to allocate the pixelref for the dst
* bitmap. If this is null, the standard HeapAllocator
* will be used.
* @return true if the copy could be made.
*/
bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const;
/** Makes a deep copy of this bitmap, respecting the requested config, and
* with custom allocation logic that will keep the copied pixels
* in the same domain as the source: If the src pixels are allocated for
* the cpu, then so will the dst. If the src pixels are allocated on the
* gpu (typically as a texture), the it will do the same for the dst.
* If the request cannot be fulfilled, returns false and dst is unmodified.
*/
bool deepCopyTo(SkBitmap* dst, Config c) const;
/** Returns true if this bitmap can be deep copied into the requested config
by calling copyTo().
*/
@ -596,7 +603,8 @@ private:
enum Flags {
kImageIsOpaque_Flag = 0x01,
kImageIsVolatile_Flag = 0x02
kImageIsVolatile_Flag = 0x02,
kImageIsImmutable_Flag = 0x04
};
uint32_t fRowBytes;

View File

@ -17,29 +17,49 @@
#include "SkRegion.h"
#include "SkMask.h"
/** SkBlitter and its subclasses are responsible for actually writing pixels
into memory. Besides efficiency, they handle clipping and antialiasing.
*/
class SkBlitter {
public:
virtual ~SkBlitter();
/// Blit a horizontal run of one or more pixels.
virtual void blitH(int x, int y, int width);
virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
const int16_t* runs);
/// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
/// zero-terminated run-length encoding of spans of constant alpha values.
virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]);
/// Blit a vertical run of pixels with a constant alpha value.
virtual void blitV(int x, int y, int height, SkAlpha alpha);
/// Blit a solid rectangle one or more pixels wide.
virtual void blitRect(int x, int y, int width, int height);
/** Blit a rectangle with one alpha-blended column on the left,
width (zero or more) opaque pixels, and one alpha-blended column
on the right.
The result will always be at least two pixels wide.
*/
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha);
/// Blit a pattern of pixels defined by a rectangle-clipped mask;
/// typically used for text.
virtual void blitMask(const SkMask&, const SkIRect& clip);
/* If the blitter just sets a single value for each pixel, return the
/** If the blitter just sets a single value for each pixel, return the
bitmap it draws into, and assign value. If not, return NULL and ignore
the value parameter.
*/
virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
// not virtual, just helpers
///@name non-virtual helpers
void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
void blitRegion(const SkRegion& clip);
///@}
// factories
/** @name Factories
Return the correct blitter to use given the specified context.
*/
static SkBlitter* Choose(const SkBitmap& device,
const SkMatrix& matrix,
const SkPaint& paint) {
@ -56,6 +76,7 @@ public:
const SkBitmap& src,
int left, int top,
void* storage, size_t storageSize);
///@}
private:
};
@ -85,12 +106,13 @@ public:
fClipRect = clipRect;
}
// overrides
virtual void blitH(int x, int y, int width) SK_OVERRIDE;
virtual void blitAntiH(int x, int y, const SkAlpha[],
const int16_t runs[]) SK_OVERRIDE;
virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
@ -111,12 +133,13 @@ public:
fRgn = clipRgn;
}
// overrides
virtual void blitH(int x, int y, int width) SK_OVERRIDE;
virtual void blitAntiH(int x, int y, const SkAlpha[],
const int16_t runs[]) SK_OVERRIDE;
virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
@ -125,6 +148,10 @@ private:
const SkRegion* fRgn;
};
/** Factory to set up the appropriate most-efficient wrapper blitter
to apply a clip. Returns a pointer to a member, so lifetime must
be managed carefully.
*/
class SkBlitterClipper {
public:
SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip,

View File

@ -61,6 +61,13 @@ public:
///////////////////////////////////////////////////////////////////////////
/**
* 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.
*/
SkISize getDeviceSize() const;
/** Return the canvas' device object, which may be null. The device holds
the bitmap of the pixels that the canvas draws into. The reference count
of the returned device is not changed by this call.
@ -99,23 +106,106 @@ public:
///////////////////////////////////////////////////////////////////////////
/**
* 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).
* This enum can be used with read/writePixels to perform a pixel ops to or
* from an 8888 config other than Skia's native config (SkPMColor). There
* are three byte orders supported: native, BGRA, and RGBA. Each has a
* premultiplied and unpremultiplied variant.
*
* Components of a 8888 pixel can be packed/unpacked from a 32bit word using
* either byte offsets or shift values. Byte offsets are endian-invariant
* while shifts are not. BGRA and RGBA configs are defined by byte
* orderings. The native config is defined by shift values (SK_A32_SHIFT,
* ..., SK_B32_SHIFT).
*/
enum Config8888 {
/**
* Skia's native order specified by:
* SK_A32_SHIFT, SK_R32_SHIFT, SK_G32_SHIFT, and SK_B32_SHIFT
*
* kNative_Premul_Config8888 is equivalent to SkPMColor
* kNative_Unpremul_Config8888 has the same component order as SkPMColor
* but is not premultiplied.
*/
kNative_Premul_Config8888,
kNative_Unpremul_Config8888,
/**
* low byte to high byte: B, G, R, A.
*/
kBGRA_Premul_Config8888,
kBGRA_Unpremul_Config8888,
/**
* low byte to high byte: R, G, B, A.
*/
kRGBA_Premul_Config8888,
kRGBA_Unpremul_Config8888,
};
/**
* On success (returns true), copy the canvas pixels into the bitmap.
* On failure, the bitmap parameter is left unchanged and false is
* returned.
*
* The canvas' pixels are converted to the bitmap's config. The only
* supported config is kARGB_8888_Config, though this is likely to be
* relaxed in the future. The meaning of config kARGB_8888_Config is
* modified by the enum param config8888. The default value interprets
* kARGB_8888_Config as SkPMColor
*
* If the bitmap has pixels already allocated, the canvas pixels will be
* written there. If not, bitmap->allocPixels() will be called
* automatically. If the bitmap is backed by a texture readPixels will
* fail.
*
* The actual pixels written is the intersection of the canvas' bounds, and
* the rectangle formed by the bitmap's width,height and the specified x,y.
* If bitmap pixels extend outside of that intersection, they will not be
* modified.
*
* Other failure conditions:
* * If the canvas is backed by a non-raster device (e.g. PDF) then
* readPixels will fail.
* * If bitmap is texture-backed then readPixels will fail. (This may be
* relaxed in the future.)
*
* Example that reads the entire canvas into a bitmap using the native
* SkPMColor:
* SkISize size = canvas->getDeviceSize();
* bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth,
* size.fHeight);
* if (canvas->readPixels(bitmap, 0, 0)) {
* // use the pixels
* }
*/
bool readPixels(SkBitmap* bitmap,
int x, int y,
Config8888 config8888 = kNative_Premul_Config8888);
/**
* DEPRECATED: This will be removed as soon as webkit is no longer relying
* on it. The bitmap is resized to the intersection of srcRect and the
* canvas bounds. New pixels are always allocated on success. Bitmap is
* unmodified on failure.
*/
bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
bool readPixels(SkBitmap* bitmap);
/**
* 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.
* the canvas, with the top/left corner specified by (x, y). The canvas'
* pixel values are completely replaced: there is no blending.
*
* Currently if bitmap is backed by a texture this is a no-op. This may be
* relaxed in the future.
*
* If the bitmap has config kARGB_8888_Config then the config8888 param
* will determines how the pixel valuess are intepreted. If the bitmap is
* not kARGB_8888_Config then this parameter is ignored.
*
* Note: If you are recording drawing commands on this canvas to
* SkPicture, writePixels() is ignored!
*/
void writePixels(const SkBitmap& bitmap, int x, int y);
void writePixels(const SkBitmap& bitmap,
int x, int y,
Config8888 config8888 = kNative_Premul_Config8888);
///////////////////////////////////////////////////////////////////////////
@ -197,6 +287,11 @@ public:
*/
void restoreToCount(int saveCount);
/** Returns true if drawing is currently going to a layer (from saveLayer)
* rather than to the root device.
*/
bool isDrawingToLayer() const;
/** Preconcat the current matrix with the specified translation
@param dx The distance to translate in X
@param dy The distance to translate in Y
@ -646,7 +741,7 @@ public:
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
/** Draw the text on path, with each character/glyph origin specified by the pos[]
array. The origin is interpreted by the Align setting in the paint.
@param text The text to be drawn
@ -842,6 +937,7 @@ private:
SkBounder* fBounder;
SkDevice* fLastDeviceToGainFocus;
int fLayerCount; // number of successful saveLayer calls
void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
const SkClipStack& clipStack);

View File

@ -23,6 +23,31 @@ public:
*/
virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode);
/**
* If the filter can be represented by a 5x4 matrix, this
* returns true, and sets the matrix appropriately.
* If not, this returns false and ignores the parameter.
*/
virtual bool asColorMatrix(SkScalar matrix[20]);
/**
* If the filter can be represented by per-component table, return true,
* and if table is not null, copy the bitmap containing the table into it.
*
* The table bitmap will be in SkBitmap::kA8_Config. Each row corresponding
* to each component in ARGB order. e.g. row[0] == alpha, row[1] == red,
* etc. To transform a color, you (logically) perform the following:
*
* a' = *table.getAddr8(a, 0);
* r' = *table.getAddr8(r, 1);
* g' = *table.getAddr8(g, 2);
* b' = *table.getAddr8(b, 3);
*
* The original component value is the horizontal index for a given row,
* and the stored value at that index is the new value for that component.
*/
virtual bool asComponentTable(SkBitmap* table);
/** Called with a scanline of colors, as if there was a shader installed.
The implementation writes out its filtered version into result[].
Note: shader and result may be the same buffer.
@ -93,6 +118,7 @@ public:
*/
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkColorFilter() {}
SkColorFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}

View File

@ -32,30 +32,32 @@ public:
virtual ~SkColorShader();
virtual uint32_t getFlags() { return fFlags; }
virtual uint8_t getSpan16Alpha() const;
virtual uint32_t getFlags() SK_OVERRIDE;
virtual uint8_t getSpan16Alpha() const SK_OVERRIDE;
virtual bool isOpaque() const SK_OVERRIDE;
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
const SkMatrix& matrix);
virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
const SkMatrix& matrix) SK_OVERRIDE;
virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE;
// we return false for this, use asAGradient
virtual BitmapType asABitmap(SkBitmap* outTexture,
SkMatrix* outMatrix,
TileMode xy[2],
SkScalar* twoPointRadialParams) const;
SkScalar* twoPointRadialParams) const SK_OVERRIDE;
virtual GradientType asAGradient(GradientInfo* info) const;
virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
protected:
SkColorShader(SkFlattenableReadBuffer&);
virtual void flatten(SkFlattenableWriteBuffer& );
virtual Factory getFactory() { return CreateProc; }
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkColorShader, (buffer));
}
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SkColor fColor; // ignored if fInheritColor is true
SkPMColor fPMColor; // cached after setContext()
uint32_t fFlags; // cached after setContext()

View File

@ -107,30 +107,28 @@ public:
const SkBitmap& accessBitmap(bool changePixels);
/**
* 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 bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
/**
* DEPRECATED: This will be made protected once WebKit stops using it.
* Instead use Canvas' writePixels method.
*
* Similar to draw sprite, this method will copy the pixels in bitmap onto
* the device, with the top/left corner specified by (x, y). The pixel
* values in the device are completely replaced: there is no blending.
*
* Currently if bitmap is backed by a texture this is a no-op. This may be
* relaxed in the future.
*
* If the bitmap has config kARGB_8888_Config then the config8888 param
* will determines how the pixel valuess are intepreted. If the bitmap is
* not kARGB_8888_Config then this parameter is ignored.
*/
virtual void writePixels(const SkBitmap& bitmap, int x, int y);
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
/**
* Return the device's associated gpu render target, or 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
@ -138,6 +136,12 @@ protected:
*/
const SkIPoint& getOrigin() const { return fOrigin; }
protected:
enum Usage {
kGeneral_Usage,
kSaveLayer_Usage, // <! internal use only
};
struct TextFlags {
uint32_t fFlags; // SkPaint::getFlags()
SkPaint::Hinting fHinting;
@ -226,7 +230,7 @@ protected:
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix);
@ -242,6 +246,37 @@ protected:
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
const SkPaint&);
/**
* On success (returns true), copy the device pixels into the bitmap.
* On failure, the bitmap parameter is left unchanged and false is
* returned.
*
* The device's pixels are converted to the bitmap's config. The only
* supported config is kARGB_8888_Config, though this is likely to be
* relaxed in the future. The meaning of config kARGB_8888_Config is
* modified by the enum param config8888. The default value interprets
* kARGB_8888_Config as SkPMColor
*
* If the bitmap has pixels already allocated, the device pixels will be
* written there. If not, bitmap->allocPixels() will be called
* automatically. If the bitmap is backed by a texture readPixels will
* fail.
*
* The actual pixels written is the intersection of the device's bounds,
* and the rectangle formed by the bitmap's width,height and the specified
* x,y. If bitmap pixels extend outside of that intersection, they will not
* be modified.
*
* Other failure conditions:
* * If the device is not a raster device (e.g. PDF) then readPixels will
* fail.
* * If bitmap is texture-backed then readPixels will fail. (This may be
* relaxed in the future.)
*/
bool readPixels(SkBitmap* bitmap,
int x, int y,
SkCanvas::Config8888 config8888);
///////////////////////////////////////////////////////////////////////////
/** Update as needed the pixel value in the bitmap, so that the caller can access
@ -257,18 +292,43 @@ protected:
return pr;
}
/**
* Implements readPixels API. The caller will ensure that:
* 1. bitmap has pixel config kARGB_8888_Config.
* 2. bitmap has pixels.
* 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is
* contained in the device bounds.
*/
virtual bool onReadPixels(const SkBitmap& bitmap,
int x, int y,
SkCanvas::Config8888 config8888);
/** 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();
/**
* Override and return true for filters that the device handles
* intrinsically. Returning false means call the filter.
* Default impl returns false.
*/
virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset);
// 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;
private:
friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip
friend class SkDraw;
friend class SkDrawIter;
friend class SkDeviceFilteredPaint;
friend class DeviceImageFilterProxy;
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }

View File

@ -55,7 +55,7 @@ public:
int scalarsPerPosition, const SkPaint& paint) const;
void drawTextOnPath(const char text[], size_t byteLength,
const SkPath&, const SkMatrix*, const SkPaint&) const;
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
void drawPosTextOnPath(const char text[], size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) const;
@ -149,6 +149,7 @@ private:
const SkPath* fPath; // returned in next
SkScalar fXPos; // accumulated xpos, returned in next
SkAutoKern fAutoKern;
int fXYIndex; // cache for horizontal -vs- vertical text
};
#endif

View File

@ -15,24 +15,26 @@
/**
* \class SkEmptyShader
* A Shader that always draws nothing.
* A Shader that always draws nothing. Its setContext always returns false,
* so it never expects that its shadeSpan() methods will get called.
*/
class SK_API SkEmptyShader : public SkShader {
public:
SkEmptyShader();
SkEmptyShader() {}
virtual uint32_t getFlags();
virtual uint8_t getSpan16Alpha() const;
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
const SkMatrix& matrix);
virtual void shadeSpan(int x, int y, SkPMColor span[], int count);
virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
virtual uint32_t getFlags() SK_OVERRIDE;
virtual uint8_t getSpan16Alpha() const SK_OVERRIDE;
virtual bool setContext(const SkBitmap&, const SkPaint&,
const SkMatrix&) SK_OVERRIDE;
virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE;
protected:
SkEmptyShader(SkFlattenableReadBuffer&);
virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&);
virtual Factory getFactory() SK_OVERRIDE;
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
private:
typedef SkShader INHERITED;

View File

@ -80,6 +80,19 @@ static inline void SkEndianSwap32s(uint32_t array[], int count) {
#define SkEndian_SwapLE32(n) SkEndianSwap32(n)
#endif
// When a bytestream is embedded in a 32-bit word, how far we need to
// shift the word to extract each byte from the low 8 bits by anding with 0xff.
#ifdef SK_CPU_LENDIAN
#define SkEndian_Byte0Shift 0
#define SkEndian_Byte1Shift 8
#define SkEndian_Byte2Shift 16
#define SkEndian_Byte3Shift 24
#else // SK_CPU_BENDIAN
#define SkEndian_Byte0Shift 24
#define SkEndian_Byte1Shift 16
#define SkEndian_Byte2Shift 8
#define SkEndian_Byte3Shift 0
#endif
#endif

View File

@ -20,6 +20,40 @@ class SkFlattenableReadBuffer;
class SkFlattenableWriteBuffer;
class SkString;
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
#define SK_DECLARE_FLATTENABLE_REGISTRAR()
#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
flattenable::CreateProc);
#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable)
#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
static SkFlattenable::Registrar g##flattenable##Reg(#flattenable, \
flattenable::CreateProc);
#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#else
#define SK_DECLARE_FLATTENABLE_REGISTRAR() static void Init();
#define SK_DEFINE_FLATTENABLE_REGISTRAR(flattenable) \
void flattenable::Init() { \
SkFlattenable::Registrar(#flattenable, CreateProc); \
}
#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(flattenable) \
void flattenable::Init() {
#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \
SkFlattenable::Registrar(#flattenable, flattenable::CreateProc);
#define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \
}
#endif
/** \class SkFlattenable
SkFlattenable is the base class for objects that need to be flattened
@ -61,6 +95,13 @@ public:
protected:
SkFlattenable(SkFlattenableReadBuffer&) {}
private:
#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
static void InitializeFlattenables();
#endif
friend class SkGraphics;
};
// helpers for matrix and region

View File

@ -63,7 +63,19 @@ static inline float sk_float_copysign(float x, float y) {
#define sk_float_mod(x,y) fmodf(x,y)
#define sk_float_exp(x) expf(x)
#define sk_float_log(x) logf(x)
#define sk_float_isNaN(x) _isnan(x)
#endif
#ifdef SK_BUILD_FOR_WIN
#define sk_float_isfinite(x) _finite(x)
#define sk_float_isnan(x) _isnan(x)
static inline int sk_float_isinf(float x) {
int32_t bits = SkFloat2Bits(x);
return (bits << 1) == (0xFF << 24);
}
#else
#define sk_float_isfinite(x) isfinite(x)
#define sk_float_isnan(x) isnan(x)
#define sk_float_isinf(x) isinf(x)
#endif
#ifdef SK_USE_FLOATBITS

View File

@ -232,20 +232,9 @@ public:
///////////////////////////////////////////////////////////////////////////
/** Return the number of bytes (approx) that should be purged from the font
cache. The input parameter is the cache's estimate of how much as been
allocated by the cache so far.
To purge (basically) everything, return the input parameter.
To purge nothing, return 0
*/
static size_t ShouldPurgeFontCache(size_t sizeAllocatedSoFar);
/** DEPRECATED -- only called by SkFontHost_FreeType internally
/** Return SkScalerContext gamma flag, or 0, based on the paint that will be
used to draw something with antialiasing.
*/
static int ComputeGammaFlag(const SkPaint& paint);
/** Return NULL or a pointer to 256 bytes for the black (table[0]) and
Return NULL or a pointer to 256 bytes for the black (table[0]) and
white (table[1]) gamma tables.
*/
static void GetGammaTables(const uint8_t* tables[2]);
@ -286,7 +275,7 @@ public:
static void SetSubpixelOrder(LCDOrder order);
static LCDOrder GetSubpixelOrder();
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
///////////////////////////////////////////////////////////////////////////
/**
@ -297,6 +286,14 @@ public:
*/
static uint32_t GetUnitsPerEm(SkFontID fontID);
#endif
/** If Skia is running in a constrained environment and the typeface
implementation is handle based, the typeface data may become
unavailable asynchronously. If a font host or scaler context method is
unable to access font data, it may call this function as a request to
make the handle contained in the typeface useable.
*/
static void EnsureTypefaceAccessible(const SkTypeface& typeface);
};
#endif

View File

@ -14,24 +14,57 @@
class SkGraphics {
public:
/**
* Call this at process initialization time if your environment does not
* permit static global initializers that execute code. Note that
* Init() is not thread-safe.
*/
static void Init();
/**
* Call this to release any memory held privately, such as the font cache.
*/
static void Term();
/** Return the (approximate) number of bytes used by the font cache.
*/
static size_t GetFontCacheUsed();
/** Attempt to purge the font cache until <= the specified amount remains
in the cache. Specifying 0 will attempt to purge the entire cache.
Returns true if some amount was purged from the font cache.
*/
static bool SetFontCacheUsed(size_t usageInBytes);
/** Return the version numbers for the library. If the parameter is not
null, it is set to the version number.
/**
* Return the version numbers for the library. If the parameter is not
* null, it is set to the version number.
*/
static void GetVersion(int32_t* major, int32_t* minor, int32_t* patch);
/**
* Return the max number of bytes that should be used by the font cache.
* If the cache needs to allocate more, it will purge previous entries.
* This max can be changed by calling SetFontCacheLimit().
*/
static size_t GetFontCacheLimit();
/**
* Specify the max number of bytes that should be used by the font cache.
* If the cache needs to allocate more, it will purge previous entries.
*
* This function returns the previous setting, as if GetFontCacheLimit()
* had be called before the new limit was set.
*/
static size_t SetFontCacheLimit(size_t bytes);
/**
* For debugging purposes, this will attempt to purge the font cache. It
* does not change the limit, but will cause subsequent font measures and
* draws to be recreated, since they will no longer be in the cache.
*/
static void PurgeFontCache();
/**
* Applications with command line options may pass optional state, such
* as cache sizes, here, for instance:
* font-cache-limit=12345678
*
* The flags format is name=value[;name=value...] with no spaces.
* This format is subject to change.
*/
static void SetFlags(const char* flags);
private:
/** This is automatically called by SkGraphics::Init(), and must be
implemented by the host OS. This allows the host OS to register a callback

View File

@ -10,8 +10,44 @@
#include "SkFlattenable.h"
class SkImageFilter : public SkFlattenable {
class SkBitmap;
class SkDevice;
class SkMatrix;
struct SkPoint;
/**
* Experimental.
*
* Base class for image filters. If one is installed in the paint, then
* all drawing occurs as usual, but it is as if the drawing happened into an
* offscreen (before the xfermode is applied). This offscreen bitmap will
* then be handed to the imagefilter, who in turn creates a new bitmap which
* is what will finally be drawn to the device (using the original xfermode).
*
* THIS SIGNATURE IS TEMPORARY
*
* There are several weaknesses in this function signature:
* 1. Does not expose the destination/target device, so filters that can draw
* directly to it are unable to take advantage of that optimization.
* 2. Does not expose a way to create a "compabitible" image (i.e. gpu -> gpu)
* 3. As with #1, the filter is unable to "read" the dest (which would be slow)
*
* Therefore, we should not create any real dependencies on this API yet -- it
* is being checked in as a check-point so we can explore these and other
* considerations.
*/
class SK_API SkImageFilter : public SkFlattenable {
public:
class Proxy {
public:
virtual SkDevice* createDevice(int width, int height) = 0;
// returns true if the proxy handled the filter itself. if this returns
// false then the filter's code will be called.
virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) = 0;
};
/**
* Request a new (result) image to be created from the src image.
@ -26,12 +62,32 @@ public:
* If the result image cannot be created, return false, in which case both
* the result and offset parameters will be ignored by the caller.
*/
bool filterImage(const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkPoint* offset);
bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset);
/**
* Given the src bounds of an image, this returns the bounds of the result
* image after the filter has been applied.
*/
bool filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst);
/**
* Experimental.
*
* If the filter can be expressed as a gaussian-blur, return true and
* set the sigma to the values for horizontal and vertical.
*/
virtual bool asABlur(SkSize* sigma) const;
protected:
virtual bool onFilterImage(const SkBitmap& src, const SkMatrix&
SkBitmap* result, SkPoint* offset) = 0;
SkImageFilter() {}
explicit SkImageFilter(SkFlattenableReadBuffer& rb) : INHERITED(rb) {}
// Default impl returns false
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* offset);
// Default impl copies src into dst and returns true
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*);
private:
typedef SkFlattenable INHERITED;

View File

@ -19,7 +19,6 @@ public:
virtual void setMemory(const void* data, size_t length, bool);
private:
int fFildes;
void* fAddr;
size_t fSize;

View File

@ -37,6 +37,7 @@ public:
return SkNEW_ARGS(SkMallocPixelRef, (buffer));
}
SK_DECLARE_PIXEL_REF_REGISTRAR()
protected:
// overrides from SkPixelRef
virtual void* onLockPixels(SkColorTable**);

View File

@ -13,7 +13,7 @@
#include "SkString.h"
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
#include <dirent.h>
#endif
@ -58,7 +58,7 @@ public:
#ifdef SK_BUILD_FOR_WIN
HANDLE fHandle;
uint16_t* fPath16;
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
DIR* fDIR;
SkString fPath, fSuffix;
#endif

View File

@ -21,6 +21,7 @@ class SkFlattenableWriteBuffer;
struct SkGlyph;
struct SkRect;
class SkGlyphCache;
class SkImageFilter;
class SkMaskFilter;
class SkMatrix;
class SkPath;
@ -98,9 +99,7 @@ public:
kLCDRenderText_Flag = 0x200, //!< mask to enable subpixel glyph renderering
kEmbeddedBitmapText_Flag = 0x400, //!< mask to enable embedded bitmap strikes
kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter
// experimental/private
kForceAAText_Flag = 0x1000,
kVerticalText_Flag = 0x1000,
// when adding extra flags, note that the fFlags member is specified
// with a bit-width and you'll have to expand it.
@ -202,6 +201,20 @@ public:
*/
void setAutohinted(bool useAutohinter);
bool isVerticalText() const {
return SkToBool(this->getFlags() & kVerticalText_Flag);
}
/**
* Helper for setting or clearing the kVerticalText_Flag bit in
* setFlags(...).
*
* If this bit is set, then advances are treated as Y values rather than
* X values, and drawText will places its glyphs vertically rather than
* horizontally.
*/
void setVerticalText(bool);
/** Helper for getFlags(), returning true if kUnderlineText_Flag bit is set
@return true if the underlineText bit is set in the paint's flags.
*/
@ -595,6 +608,9 @@ public:
*/
SkRasterizer* setRasterizer(SkRasterizer* rasterizer);
SkImageFilter* getImageFilter() const { return fImageFilter; }
SkImageFilter* setImageFilter(SkImageFilter*);
/**
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
* reference count.
@ -743,22 +759,28 @@ public:
return this->textToGlyphs(text, byteLength, NULL);
}
/** Return the width of the text.
@param text The text to be measured
@param length Number of bytes of text to measure
@param bounds If not NULL, returns the bounds of the text,
relative to (0, 0).
@param scale If not 0, return width as if the canvas were scaled
by this value
@return The advance width of the text
/** Return the width of the text. This will return the vertical measure
* if isVerticalText() is true, in which case the returned value should
* be treated has a height instead of a width.
*
* @param text The text to be measured
* @param length Number of bytes of text to measure
* @param bounds If not NULL, returns the bounds of the text,
* relative to (0, 0).
* @param scale If not 0, return width as if the canvas were scaled
* by this value
* @return The advance width of the text
*/
SkScalar measureText(const void* text, size_t length,
SkRect* bounds, SkScalar scale = 0) const;
/** Return the width of the text.
@param text Address of the text
@param length Number of bytes of text to measure
@return The width of the text
/** Return the width of the text. This will return the vertical measure
* if isVerticalText() is true, in which case the returned value should
* be treated has a height instead of a width.
*
* @param text Address of the text
* @param length Number of bytes of text to measure
* @return The width of the text
*/
SkScalar measureText(const void* text, size_t length) const {
return this->measureText(text, length, NULL, 0);
@ -777,32 +799,37 @@ public:
kBackward_TextBufferDirection
};
/** Return the width of the text.
@param text The text to be measured
@param length Number of bytes of text to measure
@param maxWidth Maximum width. Only the subset of text whose accumulated
widths are <= maxWidth are measured.
@param measuredWidth Optional. If non-null, this returns the actual
width of the measured text.
@param tbd Optional. The direction the text buffer should be
traversed during measuring.
@return The number of bytes of text that were measured. Will be
<= length.
/** Return the number of bytes of text that were measured. If
* isVerticalText() is true, then the vertical advances are used for
* the measurement.
*
* @param text The text to be measured
* @param length Number of bytes of text to measure
* @param maxWidth Maximum width. Only the subset of text whose accumulated
* widths are <= maxWidth are measured.
* @param measuredWidth Optional. If non-null, this returns the actual
* width of the measured text.
* @param tbd Optional. The direction the text buffer should be
* traversed during measuring.
* @return The number of bytes of text that were measured. Will be
* <= length.
*/
size_t breakText(const void* text, size_t length, SkScalar maxWidth,
SkScalar* measuredWidth = NULL,
TextBufferDirection tbd = kForward_TextBufferDirection)
const;
/** Return the advance widths for the characters in the string.
@param text the text
@param byteLength number of bytes to of text
@param widths If not null, returns the array of advance widths of
the glyphs. If not NULL, must be at least a large
as the number of unichars in the specified text.
@param bounds If not null, returns the bounds for each of
character, relative to (0, 0)
@return the number of unichars in the specified text.
/** Return the advances for the text. These will be vertical advances if
* isVerticalText() returns true.
*
* @param text the text
* @param byteLength number of bytes to of text
* @param widths If not null, returns the array of advances for
* the glyphs. If not NULL, must be at least a large
* as the number of unichars in the specified text.
* @param bounds If not null, returns the bounds for each of
* character, relative to (0, 0)
* @return the number of unichars in the specified text.
*/
int getTextWidths(const void* text, size_t byteLength, SkScalar widths[],
SkRect bounds[] = NULL) const;
@ -814,10 +841,7 @@ public:
void getTextPath(const void* text, size_t length, SkScalar x, SkScalar y,
SkPath* path) const;
void getPosTextPath(const void* text, size_t length,
const SkPoint pos[], SkPath* path) const;
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
const SkGlyph& getUnicharMetrics(SkUnichar);
const void* findImage(const SkGlyph&);
@ -841,20 +865,18 @@ private:
SkColorFilter* fColorFilter;
SkRasterizer* fRasterizer;
SkDrawLooper* fLooper;
SkImageFilter* fImageFilter;
SkColor fColor;
SkScalar fWidth;
SkScalar fMiterLimit;
unsigned fFlags : 13;
unsigned fFlags : 14;
unsigned fTextAlign : 2;
unsigned fCapType : 2;
unsigned fJoinType : 2;
unsigned fStyle : 2;
unsigned fTextEncoding : 2; // 3 values
unsigned fHinting : 2;
#ifdef ANDROID
uint32_t fGenerationID;
#endif
SkDrawCacheProc getDrawCacheProc() const;
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
@ -880,6 +902,12 @@ private:
friend class SkDraw;
friend class SkPDFDevice;
friend class SkTextToPathIter;
#ifdef SK_BUILD_FOR_ANDROID
// In order for the == operator to work properly this must be the last field
// in the struct so that we can do a memcmp to this field's offset.
uint32_t fGenerationID;
#endif
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -13,7 +13,7 @@
#include "SkMatrix.h"
#include "SkTDArray.h"
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
#define GEN_ID_INC fGenerationID++
#define GEN_ID_PTR_INC(ptr) ptr->fGenerationID++
#else
@ -180,6 +180,35 @@ public:
*/
bool isEmpty() const;
/** Test a line for zero length
@return true if the line is of zero length; otherwise false.
*/
static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) {
return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero);
}
/** Test a quad for zero length
@return true if the quad is of zero length; otherwise false.
*/
static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2,
const SkPoint& p3) {
return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero) &&
p2.equalsWithinTolerance(p3, SK_ScalarNearlyZero);
}
/** Test a cubic curve for zero length
@return true if the cubic is of zero length; otherwise false.
*/
static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2,
const SkPoint& p3, const SkPoint& p4) {
return p1.equalsWithinTolerance(p2, SK_ScalarNearlyZero) &&
p2.equalsWithinTolerance(p3, SK_ScalarNearlyZero) &&
p3.equalsWithinTolerance(p4, SK_ScalarNearlyZero);
}
/** Returns true if the path specifies a rectangle. If so, and if rect is
not null, set rect to the bounds of the path. If the path does not
specify a rectangle, return false and ignore rect.
@ -594,6 +623,12 @@ public:
/** Iterate through all of the segments (lines, quadratics, cubics) of
each contours in a path.
The iterator cleans up the segments along the way, removing degenerate
segments and adding close verbs where necessary. When the forceClose
argument is provided, each contour (as defined by a new starting
move command) will be completed with a close verb regardless of the
contour's contents.
*/
class SK_API Iter {
public:
@ -633,11 +668,37 @@ public:
SkPoint fLastPt;
SkBool8 fForceClose;
SkBool8 fNeedClose;
SkBool8 fNeedMoveTo;
SkBool8 fCloseLine;
SkBool8 fSegmentState;
bool cons_moveTo(SkPoint pts[1]);
Verb autoClose(SkPoint pts[2]);
void consumeDegenerateSegments();
};
/** Iterate through the verbs in the path, providing the associated points.
*/
class SK_API RawIter {
public:
RawIter();
RawIter(const SkPath&);
void setPath(const SkPath&);
/** Return the next verb in this iteration of the path. When all
segments have been visited, return kDone_Verb.
@param pts The points representing the current verb and/or segment
@return The verb for the current segment
*/
Verb next(SkPoint pts[4]);
private:
const SkPoint* fPts;
const uint8_t* fVerbs;
const uint8_t* fVerbStop;
SkPoint fMoveTo;
SkPoint fLastPt;
};
void dump(bool forceClose, const char title[] = NULL) const;
@ -646,7 +707,7 @@ public:
void flatten(SkWriter32&) const;
void unflatten(SkReader32&);
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
uint32_t getGenerationID() const;
#endif
@ -660,7 +721,7 @@ private:
uint8_t fSegmentMask;
mutable uint8_t fBoundsIsDirty;
mutable uint8_t fConvexity;
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
uint32_t fGenerationID;
#endif
@ -688,4 +749,3 @@ private:
};
#endif

View File

@ -34,6 +34,7 @@ public:
*/
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width) = 0;
SK_DECLARE_FLATTENABLE_REGISTRAR()
private:
// illegal
SkPathEffect(const SkPathEffect&);

View File

@ -10,10 +10,10 @@
#ifndef SkPixelRef_DEFINED
#define SkPixelRef_DEFINED
#include "SkBitmap.h"
#include "SkRefCnt.h"
#include "SkString.h"
class SkBitmap;
class SkColorTable;
struct SkIRect;
class SkMutex;
@ -23,6 +23,25 @@ class SkFlattenableWriteBuffer;
// this is an opaque class, not interpreted by skia
class SkGpuTexture;
#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
#define SK_DECLARE_PIXEL_REF_REGISTRAR()
#define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
static SkPixelRef::Registrar g##pixelRef##Reg(#pixelRef, \
pixelRef::Create);
#else
#define SK_DECLARE_PIXEL_REF_REGISTRAR() static void Init();
#define SK_DEFINE_PIXEL_REF_REGISTRAR(pixelRef) \
void pixelRef::Init() { \
SkPixelRef::Registrar(#pixelRef, Create); \
}
#endif
/** \class SkPixelRef
This class is the smart container for pixel memory, and is used with
@ -117,6 +136,12 @@ public:
bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
/** Makes a deep copy of this PixelRef, respecting the requested config.
Returns NULL if either there is an error (e.g. the destination could
not be created with the given config), or this PixelRef does not
support deep copies. */
virtual SkPixelRef* deepCopy(SkBitmap::Config config) { return NULL; }
// serialization
typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
@ -124,7 +149,7 @@ public:
virtual Factory getFactory() const { return NULL; }
virtual void flatten(SkFlattenableWriteBuffer&) const;
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
/**
* Acquire a "global" ref on this object.
* The default implementation just calls ref(), but subclasses can override
@ -181,6 +206,10 @@ protected:
SkPixelRef(SkFlattenableReadBuffer&, SkMutex*);
private:
#if !SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
static void InitializeFlattenables();
#endif
SkMutex* fMutex; // must remain in scope for the life of this object
void* fPixels;
SkColorTable* fColorTable; // we do not track ownership, subclass does
@ -192,6 +221,8 @@ private:
// can go from false to true, but never from true to false
bool fIsImmutable;
friend class SkGraphics;
};
#endif

View File

@ -315,6 +315,13 @@ struct SK_API SkPoint {
return a.fX != b.fX || a.fY != b.fY;
}
/** Return true if this and the given point are componentwise within tol.
*/
bool equalsWithinTolerance(const SkPoint& v, SkScalar tol) const {
return SkScalarNearlyZero(fX - v.fX, tol)
&& SkScalarNearlyZero(fY - v.fY, tol);
}
/** Returns a new point whose coordinates are the difference between
a's and b's (a - b)
*/

View File

@ -56,6 +56,32 @@
#endif
#endif
#if !defined(SK_HAS_COMPILER_FEATURE)
#if defined(__has_feature)
#define SK_HAS_COMPILER_FEATURE(x) __has_feature(x)
#else
#define SK_HAS_COMPILER_FEATURE(x) 0
#endif
#endif
/**
* The clang static analyzer likes to know that when the program is not
* expected to continue (crash, assertion failure, etc). It will notice that
* some combination of parameters lead to a function call that does not return.
* It can then make appropriate assumptions about the parameters in code
* executed only if the non-returning function was *not* called.
*/
#if !defined(SkNO_RETURN_HINT)
#if SK_HAS_COMPILER_FEATURE(attribute_analyzer_noreturn)
namespace {
inline void SkNO_RETURN_HINT() __attribute__((analyzer_noreturn));
void SkNO_RETURN_HINT() {}
}
#else
#define SkNO_RETURN_HINT() do {} while (false)
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
#ifndef SkNEW
@ -68,9 +94,9 @@
#ifndef SK_CRASH
#if 1 // set to 0 for infinite loop, which can help connecting gdb
#define SK_CRASH() *(int *)(uintptr_t)0xbbadbeef = 0
#define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
#else
#define SK_CRASH() do {} while (true)
#define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
#endif
#endif
@ -100,7 +126,7 @@
#endif
#ifndef SK_DEBUGBREAK
#define SK_DEBUGBREAK(cond) do { if (!(cond)) __debugbreak(); } while (false)
#define SK_DEBUGBREAK(cond) do { if (!(cond)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
#endif
#ifndef SK_A32_SHIFT
@ -265,3 +291,8 @@
#endif
#endif
//////////////////////////////////////////////////////////////////////
#ifndef SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 1
#endif

View File

@ -16,7 +16,7 @@
//////////////////////////////////////////////////////////////////////
#if !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_SYMBIAN) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW)
#ifdef __APPLE__
#include "TargetConditionals.h"
@ -30,13 +30,14 @@
#define SK_BUILD_FOR_WIN32
#elif defined(__SYMBIAN32__)
#define SK_BUILD_FOR_WIN32
#elif defined(linux) || defined(__OpenBSD_)
#elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__)
#define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS
#elif defined(ANDROID_NDK)
#define SK_BUILD_FOR_ANDROID_NDK
#elif defined(ANROID)
#elif defined(ANDROID)
#define SK_BUILD_FOR_ANDROID
#else
#define SK_BUILD_FOR_MAC
@ -44,6 +45,15 @@
#endif
/* Even if the user only defined the NDK variant we still need to build
* the default Android code. Therefore, when attempting to include/exclude
* something from the NDK variant check first that we are building for
* Android then check the status of the NDK define.
*/
#if defined(SK_BUILD_FOR_ANDROID_NDK) && !defined(SK_BUILD_FOR_ANDROID)
#define SK_BUILD_FOR_ANDROID
#endif
//////////////////////////////////////////////////////////////////////
#if !defined(SK_DEBUG) && !defined(SK_RELEASE)

View File

@ -335,10 +335,34 @@ struct SK_API SkRect {
return r;
}
/** Return true if the rectangle's width or height are <= 0
/**
* Return true if the rectangle's width or height are <= 0
*/
bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
bool hasValidCoordinates() const;
/**
* Returns true iff all values in the rect are finite. If any are
* infinite or NaN (or SK_FixedNaN when SkScalar is fixed) then this
* returns false.
*/
bool isFinite() const {
#ifdef SK_SCALAR_IS_FLOAT
// x * 0 will be NaN iff x is infinity or NaN.
// a + b will be NaN iff either a or b is NaN.
float value = fLeft * 0 + fTop * 0 + fRight * 0 + fBottom * 0;
// value is either NaN or it is finite (zero).
// value==value will be true iff value is not NaN
return value == value;
#else
// use bit-or for speed, since we don't care about short-circuting the
// tests, and we expect the common case will be that we need to check all.
int isNaN = (SK_FixedNaN == fLeft) | (SK_FixedNaN == fTop) |
(SK_FixedNaN == fRight) | (SK_FixedNaN == fBottom);
return !isNaN;
#endif
}
SkScalar left() const { return fLeft; }
SkScalar top() const { return fTop; }
SkScalar right() const { return fRight; }

View File

@ -86,9 +86,9 @@ public:
const SkIRect& getBounds() const { return fBounds; }
/**
* Returns true if the region is non-empty, and if so, sets the specified
* path to the boundary(s) of the region. If the region is empty, then
* this returns false, and path is left unmodified.
* Returns true if the region is non-empty, and if so, appends the
* boundary(s) of the region to the specified path.
* If the region is empty, returns false, and path is left unmodified.
*/
bool getBoundaryPath(SkPath* path) const;
@ -283,7 +283,7 @@ public:
*/
bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
/** Returns a new char* containing the list of rectangles in this region
*/
char* toString();

View File

@ -92,7 +92,7 @@
*
* Either way, it's not good.
*/
SkASSERT(!"looks like you passed an SkScalar into SkIntToScalar");
SkDEBUGFAIL("looks like you passed an SkScalar into SkIntToScalar");
return (float)0;
}
#else // not SK_DEBUG
@ -119,7 +119,7 @@
#define SkScalarFloorToScalar(x) sk_float_floor(x)
#define SkScalarCeilToScalar(x) sk_float_ceil(x)
#define SkScalarRoundToScalar(x) sk_float_round(x)
#define SkScalarRoundToScalar(x) sk_float_floor((x) + 0.5f)
#define SkScalarFloorToInt(x) sk_float_floor2int(x)
#define SkScalarCeilToInt(x) sk_float_ceil2int(x)

View File

@ -157,33 +157,36 @@ struct SkGlyph {
class SkScalerContext {
public:
enum Flags {
kFrameAndFill_Flag = 0x01,
kDevKernText_Flag = 0x02,
kGammaForBlack_Flag = 0x04, // illegal to set both Gamma flags
kGammaForWhite_Flag = 0x08, // illegal to set both Gamma flags
kFrameAndFill_Flag = 0x0001,
kDevKernText_Flag = 0x0002,
kEmbeddedBitmapText_Flag = 0x0004,
kEmbolden_Flag = 0x0008,
kSubpixelPositioning_Flag = 0x0010,
kAutohinting_Flag = 0x0020,
kVertical_Flag = 0x0040,
// together, these two flags resulting in a two bit value which matches
// up with the SkPaint::Hinting enum.
kHintingBit1_Flag = 0x10,
kHintingBit2_Flag = 0x20,
kEmbeddedBitmapText_Flag = 0x40,
kEmbolden_Flag = 0x80,
kSubpixelPositioning_Flag = 0x100,
kAutohinting_Flag = 0x200,
kHinting_Shift = 7, // to shift into the other flags above
kHintingBit1_Flag = 0x0080,
kHintingBit2_Flag = 0x0100,
// these should only ever be set if fMaskFormat is LCD16 or LCD32
kLCD_Vertical_Flag = 0x400, // else Horizontal
kLCD_BGROrder_Flag = 0x800, // else RGB order
kLCD_Vertical_Flag = 0x0200, // else Horizontal
kLCD_BGROrder_Flag = 0x0400, // else RGB order
// experimental
kForceAA_Flag = 0x1000
// luminance : 0 for black text, kLuminance_Max for white text
kLuminance_Shift = 11, // to shift into the other flags above
kLuminance_Bits = 3, // ensure Flags doesn't exceed 16bits
};
private:
// computed values
enum {
kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag
kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag,
kLuminance_Max = (1 << kLuminance_Bits) - 1,
kLuminance_Mask = kLuminance_Max << kLuminance_Shift,
};
public:
struct Rec {
uint32_t fOrigFontID;
uint32_t fFontID;
@ -203,11 +206,29 @@ public:
void getSingleMatrix(SkMatrix*) const;
SkPaint::Hinting getHinting() const {
return static_cast<SkPaint::Hinting>((fFlags & kHintingMask) >> 4);
unsigned hint = (fFlags & kHinting_Mask) >> kHinting_Shift;
return static_cast<SkPaint::Hinting>(hint);
}
void setHinting(SkPaint::Hinting hinting) {
fFlags = (fFlags & ~kHintingMask) | (hinting << 4);
fFlags = (fFlags & ~kHinting_Mask) | (hinting << kHinting_Shift);
}
unsigned getLuminanceBits() const {
return (fFlags & kLuminance_Mask) >> kLuminance_Shift;
}
void setLuminanceBits(unsigned lum) {
SkASSERT(lum <= kLuminance_Max);
fFlags = (fFlags & ~kLuminance_Mask) | (lum << kLuminance_Shift);
}
U8CPU getLuminanceByte() const {
SkASSERT(3 == kLuminance_Bits);
unsigned lum = this->getLuminanceBits();
lum |= (lum << kLuminance_Bits);
lum |= (lum << kLuminance_Bits*2);
return lum >> (4*kLuminance_Bits - 8);
}
SkMask::Format getFormat() const {
@ -222,6 +243,10 @@ public:
return (SkMask::Format)fRec.fMaskFormat;
}
bool isSubpixel() const {
return SkToBool(fRec.fFlags & kSubpixelPositioning_Flag);
}
// remember our glyph offset/base
void setBaseGlyphCount(unsigned baseGlyphCount) {
fBaseGlyphCount = baseGlyphCount;

View File

@ -96,6 +96,15 @@ public:
*/
virtual uint32_t getFlags() { return 0; }
/**
* Returns true if the shader is guaranteed to produce only opaque
* colors, subject to the SkPaint using the shader to apply an opaque
* alpha value. Subclasses should override this to allow some
* optimizations. isOpaque() can be called at any time, unlike getFlags,
* which only works properly when the context is set.
*/
virtual bool isOpaque() const { return false; }
/**
* Return the alpha associated with the data returned by shadeSpan16(). If
* kHasSpan16_Flag is not set, this value is meaningless.

View File

@ -38,6 +38,8 @@ public:
// public for Registrar
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
virtual void onDraw(SkCanvas*);

View File

@ -299,8 +299,8 @@ protected:
void init(const T* array, int count,
void* preAllocStorage, int preAllocOrReserveCount) {
GrAssert(count >= 0);
GrAssert(preAllocOrReserveCount >= 0);
SkASSERT(count >= 0);
SkASSERT(preAllocOrReserveCount >= 0);
fCount = count;
fReserveCount = (preAllocOrReserveCount > 0) ?
preAllocOrReserveCount :
@ -311,8 +311,8 @@ protected:
fAllocCount = fReserveCount;
fMemArray = preAllocStorage;
} else {
fAllocCount = GrMax(fCount, fReserveCount);
fMemArray = GrMalloc(fAllocCount * sizeof(T));
fAllocCount = SkMax32(fCount, fReserveCount);
fMemArray = sk_malloc_throw(fAllocCount * sizeof(T));
}
SkTArrayExt::copy(this, array);

View File

@ -91,7 +91,17 @@ public:
}
bool isEmpty() const { return fCount == 0; }
/**
* Return the number of elements in the array
*/
int count() const { return fCount; }
/**
* return the number of bytes in the array: count * sizeof(T)
*/
size_t bytes() const { return fCount * sizeof(T); }
T* begin() const { return fArray; }
T* end() const { return fArray ? fArray + fCount : NULL; }
T& operator[](int index) const {

View File

@ -21,7 +21,7 @@ public:
typedef T (*Factory)(P);
SkTRegistry(Factory fact) {
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
// work-around for double-initialization bug
{
SkTRegistry* reg = gHead;

View File

@ -10,7 +10,7 @@
#ifndef SkThread_platform_DEFINED
#define SkThread_platform_DEFINED
#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
#include <utils/threads.h>
#include <utils/Atomic.h>

View File

@ -93,6 +93,7 @@ inline void operator delete(void* p) {
#ifdef SK_DEBUG
#define SkASSERT(cond) SK_DEBUGBREAK(cond)
#define SkDEBUGFAIL(message) SkASSERT(false && message)
#define SkDEBUGCODE(code) code
#define SkDECLAREPARAM(type, var) , type var
#define SkPARAM(var) , var
@ -101,6 +102,7 @@ inline void operator delete(void* p) {
#define SkAssertResult(cond) SkASSERT(cond)
#else
#define SkASSERT(cond)
#define SkDEBUGFAIL(message)
#define SkDEBUGCODE(code)
#define SkDEBUGF(args)
#define SkDECLAREPARAM(type, var)
@ -216,6 +218,8 @@ static inline bool SkIsU16(long x) {
*/
#define SkAlign4(x) (((x) + 3) >> 2 << 2)
#define SkIsAlign4(x) (((x) & 3) == 0)
typedef uint32_t SkFourByteTag;
#define SkSetFourByteTag(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))

View File

@ -32,7 +32,7 @@ void sk_memset32_portable(uint32_t dst[], uint32_t value, int count);
typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count);
SkMemset32Proc SkMemset32GetPlatformProc();
#if defined(ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
#if defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_ANDROID_NDK)
#include "cutils/memory.h"
#define sk_memset16(dst, value, count) android_memset16(dst, value, (count) << 1)
@ -91,6 +91,21 @@ size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t utf16[] = NULL);
size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
char utf8[] = NULL);
inline bool SkUnichar_IsVariationSelector(SkUnichar uni) {
/* The 'true' ranges are:
* 0x180B <= uni <= 0x180D
* 0xFE00 <= uni <= 0xFE0F
* 0xE0100 <= uni <= 0xE01EF
*/
if (uni < 0x180B || uni > 0xE01EF) {
return false;
}
if ((uni > 0x180D && uni < 0xFE00) || (uni > 0xFE0F && uni < 0xE0100)) {
return false;
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
class SkAutoTrace {

View File

@ -131,6 +131,18 @@ public:
*/
static bool AsMode(SkXfermode*, Mode* mode);
/**
* Returns true if the xfermode claims to be the specified Mode. This works
* correctly even if the xfermode is NULL (which equates to kSrcOver.) Thus
* you can say this without checking for a null...
*
* If (SkXfermode::IsMode(paint.getXfermode(),
* SkXfermode::kDstOver_Mode)) {
* ...
* }
*/
static bool IsMode(SkXfermode* xfer, Mode mode);
/** Return an SkXfermode object for the specified mode.
*/
static SkXfermode* Create(Mode mode);
@ -160,6 +172,7 @@ public:
return AsMode(xfer, mode);
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkXfermode(SkFlattenableReadBuffer& rb) : SkFlattenable(rb) {}

View File

@ -57,21 +57,23 @@ public:
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
// override from SkPathEffect
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkPath1DPathEffect, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkPath1DPathEffect(SkFlattenableReadBuffer& buffer);
// overrides from Sk1DPathEffect
virtual SkScalar begin(SkScalar contourLength);
virtual SkScalar next(SkPath* dst, SkScalar distance, SkPathMeasure&);
virtual SkScalar begin(SkScalar contourLength) SK_OVERRIDE;
virtual SkScalar next(SkPath*, SkScalar distance, SkPathMeasure&) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer& );
virtual Factory getFactory() { return CreateProc; }
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
private:
SkPath fPath; // copied from constructor

View File

@ -19,11 +19,11 @@ public:
Sk2DPathEffect(const SkMatrix& mat);
// overrides
virtual bool filterPath(SkPath* dst, const SkPath& src, SkScalar* width);
virtual bool filterPath(SkPath*, const SkPath&, SkScalar* width) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&);
virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
protected:
/** New virtual, to be overridden by subclasses.
@ -47,6 +47,8 @@ protected:
// protected so that subclasses can call this during unflattening
Sk2DPathEffect(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
private:
SkMatrix fMatrix, fInverse;
// illegal
@ -69,12 +71,14 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkPath2DPathEffect(SkFlattenableReadBuffer& buffer);
virtual void flatten(SkFlattenableWriteBuffer&);
virtual Factory getFactory();
virtual void next(const SkPoint& loc, int u, int v, SkPath* dst);
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
virtual void next(const SkPoint&, int u, int v, SkPath* dst) SK_OVERRIDE;
private:
SkPath fPath;

View File

@ -0,0 +1,30 @@
/*
* 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 SkArithmeticMode_DEFINED
#define SkArithmeticMode_DEFINED
#include "SkXfermode.h"
class SkArithmeticMode : public SkXfermode {
public:
/**
* result = clamp[k1 * src * dst + k2 * src + k3 * dst + k4]
*
* src and dst are treated as being [0.0 .. 1.0]. The polynomial is
* evaluated on their unpremultiplied components.
*
* k1=k2=k3=0, k4=1.0 results in returning opaque white
* k1=k3=k4=0, k2=1.0 results in returning the src
* k1=k2=k4=0, k3=1.0 results in returning the dst
*/
static SkXfermode* Create(SkScalar k1, SkScalar k2,
SkScalar k3, SkScalar k4);
};
#endif

View File

@ -43,22 +43,24 @@ public:
// overrides from SkXfermode
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
const SkAlpha aa[]);
const SkAlpha aa[]) SK_OVERRIDE;
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
const SkAlpha aa[]);
const SkAlpha aa[]) SK_OVERRIDE;
virtual void xfer4444(uint16_t dst[], const SkPMColor src[], int count,
const SkAlpha aa[]);
const SkAlpha aa[]) SK_OVERRIDE;
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
const SkAlpha aa[]);
const SkAlpha aa[]) SK_OVERRIDE;
// overrides from SkFlattenable
virtual Factory getFactory();
virtual void flatten(SkFlattenableWriteBuffer&);
virtual Factory getFactory() SK_OVERRIDE;
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkAvoidXfermode, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkAvoidXfermode(SkFlattenableReadBuffer&);

View File

@ -48,6 +48,7 @@ public:
return SkNEW_ARGS(SkBlurDrawLooper, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkBlurDrawLooper(SkFlattenableReadBuffer&);

View File

@ -0,0 +1,40 @@
/*
* Copyright 2011 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 SkBlurImageFilter_DEFINED
#define SkBlurImageFilter_DEFINED
#include "SkImageFilter.h"
class SK_API SkBlurImageFilter : public SkImageFilter {
public:
SkBlurImageFilter(SkScalar sigmaX, SkScalar sigmaY);
virtual bool asABlur(SkSize* sigma) const SK_OVERRIDE;
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkBlurImageFilter, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
explicit SkBlurImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
private:
SkSize fSigma;
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -55,6 +55,8 @@ public:
SkScalar ambient, SkScalar specular,
SkScalar blurRadius);
SK_DECLARE_FLATTENABLE_REGISTRAR()
private:
SkBlurMaskFilter(); // can't be instantiated
};

View File

@ -23,12 +23,13 @@ public:
void setArray(const SkScalar array[20]);
// overrides from SkColorFilter
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]);
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]);
virtual uint32_t getFlags();
virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) SK_OVERRIDE;
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) SK_OVERRIDE;
virtual uint32_t getFlags() SK_OVERRIDE;
virtual bool asColorMatrix(SkScalar matrix[20]) SK_OVERRIDE;
// overrides for SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer& buffer);
virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE;
struct State {
int32_t fArray[20];
@ -38,6 +39,8 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
// overrides for SkFlattenable
virtual Factory getFactory();

View File

@ -37,6 +37,8 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkCornerPathEffect(SkFlattenableReadBuffer&);

View File

@ -39,6 +39,8 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkDashPathEffect(SkFlattenableReadBuffer&);

View File

@ -36,6 +36,8 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkDiscretePathEffect(SkFlattenableReadBuffer&);

View File

@ -0,0 +1,16 @@
/*
* 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 SkEffects_DEFINED
#define SkEffects_DEFINED
class SkEffects {
public:
static void Init();
};
#endif

View File

@ -41,6 +41,8 @@ public:
// This method is not exported to java.
virtual void flatten(SkFlattenableWriteBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkEmbossMaskFilter(SkFlattenableReadBuffer&);

View File

@ -112,6 +112,8 @@ public:
static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
const SkColor colors[], const SkScalar pos[],
int count, SkUnitMapper* mapper = NULL);
SK_DECLARE_FLATTENABLE_REGISTRAR()
};
#endif

View File

@ -138,6 +138,8 @@ public:
// public for Registrar
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
// overrides
virtual void onDraw(SkCanvas*);

View File

@ -22,7 +22,8 @@ public:
* Bits specifies which aspects of the layer's paint should replace the
* corresponding aspects on the draw's paint.
* kEntirePaint_Bits means use the layer's paint completely.
* 0 means ignore the layer's paint.
* 0 means ignore the layer's paint... except that LayerInfo's fFlagsMask
* and fColorMode are always applied.
*/
enum Bits {
kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings
@ -33,7 +34,15 @@ public:
kColorFilter_Bit = 1 << 5, //!< use this layer's colorfilter
kXfermode_Bit = 1 << 6, //!< use this layer's xfermode
kEntirePaint_Bits = -1, //!< use this layer's paint entirely
/**
* Use the layer's paint entirely, with these exceptions:
* - We never override the draw's paint's text_encoding, since that is
* used to interpret the text/len parameters in draw[Pos]Text.
* - Flags and Color are always computed using the LayerInfo's
* fFlagsMask and fColorMode.
*/
kEntirePaint_Bits = -1,
};
typedef int32_t BitFlags;
@ -97,6 +106,8 @@ public:
return SkNEW_ARGS(SkLayerDrawLooper, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkLayerDrawLooper(SkFlattenableReadBuffer&);

View File

@ -38,6 +38,8 @@ public:
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkLayerRasterizer(SkFlattenableReadBuffer&);

View File

@ -29,6 +29,8 @@ public:
return SkNEW_ARGS(SkPixelXorXfermode, (buffer));
}
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
// override from SkXfermode
virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst);

View File

@ -45,7 +45,7 @@ public:
kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
kScreen_Mode, //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
kAdd_Mode, //!< Saturate(S + D)
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
kOverlay_Mode,
#endif

View File

@ -47,6 +47,8 @@ public:
// public for Registrar
static SkFlattenable* CreateProc(SkFlattenableReadBuffer&);
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkRectShape(SkFlattenableReadBuffer&);

View File

@ -0,0 +1,34 @@
#ifndef SkTableColorFilter_DEFINED
#define SkTableColorFilter_DEFINED
#include "SkColorFilter.h"
class SkTableColorFilter {
public:
/**
* Create a table colorfilter, copying the table into the filter, and
* applying it to all 4 components.
* a' = table[a];
* r' = table[r];
* g' = table[g];
* b' = table[b];
* Compoents are operated on in unpremultiplied space. If the incomming
* colors are premultiplied, they are temporarily unpremultiplied, then
* the table is applied, and then the result is remultiplied.
*/
static SkColorFilter* Create(const uint8_t table[256]);
/**
* Create a table colorfilter, with a different table for each
* component [A, R, G, B]. If a given table is NULL, then it is
* treated as identity, with the component left unchanged. If a table
* is not null, then its contents are copied into the filter.
*/
static SkColorFilter* CreateARGB(const uint8_t tableA[256],
const uint8_t tableR[256],
const uint8_t tableG[256],
const uint8_t tableB[256]);
};
#endif

View File

@ -0,0 +1,157 @@
#ifndef _SkTestImageFilters_h
#define _SkTestImageFilters_h
#include "SkImageFilter.h"
class SkOffsetImageFilter : public SkImageFilter {
public:
SkOffsetImageFilter(SkScalar dx, SkScalar dy) {
fOffset.set(dx, dy);
}
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkOffsetImageFilter, (buffer));
}
protected:
SkOffsetImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
SkVector fOffset;
typedef SkImageFilter INHERITED;
};
class SkComposeImageFilter : public SkImageFilter {
public:
SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) {
fOuter = outer;
fInner = inner;
SkSafeRef(outer);
SkSafeRef(inner);
}
virtual ~SkComposeImageFilter();
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkComposeImageFilter, (buffer));
}
protected:
SkComposeImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
SkImageFilter* fOuter;
SkImageFilter* fInner;
typedef SkImageFilter INHERITED;
};
#include "SkXfermode.h"
class SkMergeImageFilter : public SkImageFilter {
public:
SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second,
SkXfermode::Mode = SkXfermode::kSrcOver_Mode);
SkMergeImageFilter(SkImageFilter* const filters[], int count,
const SkXfermode::Mode modes[] = NULL);
virtual ~SkMergeImageFilter();
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkMergeImageFilter, (buffer));
}
protected:
SkMergeImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
SkImageFilter** fFilters;
uint8_t* fModes; // SkXfermode::Mode
int fCount;
// private storage, to avoid dynamically allocating storage for our copy
// of the filters and modes (unless fCount is so large we can't fit).
intptr_t fStorage[16];
void initAlloc(int count, bool hasModes);
void init(SkImageFilter* const [], int count, const SkXfermode::Mode []);
typedef SkImageFilter INHERITED;
};
class SkColorFilter;
class SkColorFilterImageFilter : public SkImageFilter {
public:
SkColorFilterImageFilter(SkColorFilter* cf) : fColorFilter(cf) {
SkSafeRef(cf);
}
virtual ~SkColorFilterImageFilter();
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkColorFilterImageFilter, (buffer));
}
protected:
SkColorFilterImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
SkColorFilter* fColorFilter;
typedef SkImageFilter INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
// Fun mode that scales down (only) and then scales back up to look pixelated
class SkDownSampleImageFilter : public SkImageFilter {
public:
SkDownSampleImageFilter(SkScalar scale) : fScale(scale) {}
static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
return SkNEW_ARGS(SkDownSampleImageFilter, (buffer));
}
protected:
SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&,
SkBitmap* result, SkIPoint* loc) SK_OVERRIDE;
// overrides from SkFlattenable
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
virtual Factory getFactory() SK_OVERRIDE;
private:
SkScalar fScale;
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -15,18 +15,17 @@
class SkTransparentShader : public SkShader {
public:
SkTransparentShader() {}
virtual uint32_t getFlags();
virtual uint32_t getFlags() SK_OVERRIDE;
virtual bool setContext( const SkBitmap& device,
const SkPaint& paint,
const SkMatrix& matrix);
virtual void shadeSpan(int x, int y, SkPMColor[], int count);
virtual void shadeSpan16(int x, int y, uint16_t span[], int count);
const SkMatrix& matrix) SK_OVERRIDE;
virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE;
// overrides for SkFlattenable
virtual Factory getFactory() { return Create; }
virtual void flatten(SkFlattenableWriteBuffer& buffer) {
this->INHERITED::flatten(buffer);
}
virtual Factory getFactory() SK_OVERRIDE;
virtual void flatten(SkFlattenableWriteBuffer&) SK_OVERRIDE;
private:
// these are a cache from the call to setContext()

View File

@ -19,15 +19,12 @@
*/
typedef uint32_t GrColor;
// indices for address a GrColor as an array of bytes
#define GrColor_INDEX_R 0
#define GrColor_INDEX_G 1
#define GrColor_INDEX_B 2
#define GrColor_INDEX_A 3
// shfit amount to assign a component to a GrColor int
// shift amount to assign a component to a GrColor int
// These shift values are chosen for compatibility with GL attrib arrays
// ES doesn't allow BGRA vertex attrib order so if they were not in this order
// we'd have to swizzle in shaders. Note the assumption that the cpu is little
// endian.
#define GrColor_SHIFT_R 0
#define GrColor_SHIFT_G 8
#define GrColor_SHIFT_B 16

View File

@ -61,7 +61,7 @@
#undef GR_IOS_BUILD
#define GR_IOS_BUILD 1
// #error "IOS"
#elif (defined(ANDROID_NDK) && ANDROID_NDK) || defined(ANDROID)
#elif defined(SK_BUILD_FOR_ANDROID)
#undef GR_ANDROID_BUILD
#define GR_ANDROID_BUILD 1
// #error "ANDROID"
@ -220,12 +220,12 @@ extern GR_API void GrPrintf(const char format[], ...);
*/
#if !defined(GR_ALWAYSBREAK)
#if GR_WIN32_BUILD
#define GR_ALWAYSBREAK __debugbreak()
#define GR_ALWAYSBREAK SkNO_RETURN_HINT(); __debugbreak()
#else
// TODO: do other platforms really not have continuable breakpoints?
// sign extend for 64bit architectures to be sure this is
// in the high address range
#define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
#define GR_ALWAYSBREAK SkNO_RETURN_HINT(); *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
#endif
#endif
@ -351,7 +351,7 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
* program.
*/
#if !defined(GR_AGGRESSIVE_SHADER_OPTS)
#define GR_AGGRESSIVE_SHADER_OPTS 0
#define GR_AGGRESSIVE_SHADER_OPTS 1
#endif
/**
@ -380,6 +380,7 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
#define GR_MAX_OFFSCREEN_AA_SIZE 256
#endif
///////////////////////////////////////////////////////////////////////////////
// tail section:
//

View File

@ -39,11 +39,6 @@ public:
static GrContext* Create(GrEngine engine,
GrPlatform3DContext context3D);
/**
* Helper to create a opengl-shader based context
*/
static GrContext* CreateGLShaderContext();
virtual ~GrContext();
/**
@ -112,24 +107,62 @@ public:
*/
typedef uint64_t TextureKey;
/**
* Create a new entry, based on the specified key and texture, and return
* its "locked" entry. Must call be balanced with an unlockTexture() call.
*
* @param key A client-generated key that identifies the contents
* of the texture. Respecified to findAndLockTexture
* for subsequent uses of the texture.
* @param sampler The sampler state used to draw a texture may be used
* to determine how to store the pixel data in the texture
* cache. (e.g. different versions may exist for different
* wrap modes on GPUs with limited or no NPOT texture
* support). Only the wrap and filter fields are used. NULL
* implies clamp wrap modes and nearest filtering.
* @param desc Description of the texture properties.
* @param srcData Pointer to the pixel values.
* @param rowBytes The number of bytes between rows of the texture. Zero
* implies tightly packed rows.
*/
TextureCacheEntry createAndLockTexture(TextureKey key,
const GrSamplerState* sampler,
const GrTextureDesc& desc,
void* srcData, size_t rowBytes);
/**
* Search for an entry based on key and dimensions. If found, "lock" it and
* return it. The entry's texture() function will return NULL if not found.
* Must call be balanced with an unlockTexture() call.
* Must be balanced with an unlockTexture() call.
*
* @param key A client-generated key that identifies the contents
* of the texture.
* @param width The width of the texture in pixels as specifed in
* the GrTextureDesc originally passed to
* createAndLockTexture
* @param width The height of the texture in pixels as specifed in
* the GrTextureDesc originally passed to
* createAndLockTexture
* @param sampler The sampler state used to draw a texture may be used
* to determine the cache entry used. (e.g. different
* versions may exist for different wrap modes on GPUs with
* limited or no NPOT texture support). Only the wrap and
* filter fields are used. NULL implies clamp wrap modes
* and nearest filtering.
*/
TextureCacheEntry findAndLockTexture(TextureKey key,
int width,
int height,
const GrSamplerState&);
const GrSamplerState* sampler);
/**
* Create a new entry, based on the specified key and texture, and return
* its "locked" entry. Must call be balanced with an unlockTexture() call.
* Determines whether a texture is in the cache. If the texture is found it
* will not be locked or returned. This call does not affect the priority of
* the texture for deletion.
*/
TextureCacheEntry createAndLockTexture(TextureKey key,
const GrSamplerState&,
const GrTextureDesc&,
void* srcData, size_t rowBytes);
bool isTextureInCache(TextureKey key,
int width,
int height,
const GrSamplerState*) const;
/**
* Enum that determines how closely a returned scratch texture must match
@ -182,7 +215,7 @@ public:
/**
* Returns true if the specified use of an indexed texture is supported.
*/
bool supportsIndex8PixelConfig(const GrSamplerState&,
bool supportsIndex8PixelConfig(const GrSamplerState*,
int width,
int height) const;
@ -238,6 +271,35 @@ public:
// Platform Surfaces
/**
* Wraps an existing texture with a GrTexture object.
*
* OpenGL: if the object is a texture Gr may change its GL texture params
* when it is drawn.
*
* @param desc description of the object to create.
*
* @return GrTexture object or NULL on failure.
*/
GrTexture* createPlatformTexture(const GrPlatformTextureDesc& desc);
/**
* Wraps an existing render target with a GrRenderTarget object. It is
* similar to createPlatformTexture but can be used to draw into surfaces
* that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
* the client will resolve to a texture).
*
* @param desc description of the object to create.
*
* @return GrTexture object or NULL on failure.
*/
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
@ -424,7 +486,7 @@ public:
/**
* Reads a rectangle of pixels from a render target.
* @param renderTarget the render target to read from. NULL means the
* @param target the render target to read from. NULL means the
* current render target.
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
@ -432,39 +494,94 @@ public:
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*
* @return true if the read succeeded, false if not. The read can fail
* because of a unsupported pixel config or because no render
* because of an unsupported pixel config or because no render
* target is currently set.
*/
bool readRenderTargetPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig config, void* buffer);
GrPixelConfig config, void* buffer,
size_t rowBytes) {
return this->internalReadRenderTargetPixels(target, left, top,
width, height,
config, buffer,
rowBytes, 0);
}
/**
* Copy the src pixels [buffer, rowbytes, pixelconfig] into a render target
* at the specified rectangle.
* @param target the render target to write into. NULL means the
* current render target.
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param buffer memory to read the rectangle from.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*/
void writeRenderTargetPixels(GrRenderTarget* target,
int left, int top, int width, int height,
GrPixelConfig config, const void* buffer,
size_t rowBytes) {
this->internalWriteRenderTargetPixels(target, left, top, width, height,
config, buffer, rowBytes, 0);
}
/**
* Reads a rectangle of pixels from a texture.
* @param texture the render target to read from.
* @param texture the texture to read from.
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
* @param width width of rectangle to read in pixels.
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*
* @return true if the read succeeded, false if not. The read can fail
* because of a unsupported pixel config.
* because of an unsupported pixel config.
*/
bool readTexturePixels(GrTexture* target,
bool readTexturePixels(GrTexture* texture,
int left, int top, int width, int height,
GrPixelConfig config, void* buffer);
GrPixelConfig config, void* buffer,
size_t rowBytes) {
return this->internalReadTexturePixels(texture, left, top,
width, height,
config, buffer, rowBytes, 0);
}
/**
* Copy the src pixels [buffer, stride, pixelconfig] into the current
* render-target at the specified rectangle.
* Writes a rectangle of pixels to a texture.
* @param texture the render target to read from.
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param buffer memory to read pixels from
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*/
void writePixels(int left, int top, int width, int height,
GrPixelConfig, const void* buffer, size_t stride);
void writeTexturePixels(GrTexture* texture,
int left, int top, int width, int height,
GrPixelConfig config, const void* buffer,
size_t rowBytes) {
this->internalWriteTexturePixels(texture, left, top, width, height,
config, buffer, rowBytes, 0);
}
/**
* Copies all texels from one texture to another.
* @param src the texture to copy from.
* @param dst the render target to copy to.
*/
void copyTexture(GrTexture* src, GrRenderTarget* dst);
/**
* Applies a 1D convolution kernel in the X direction to a rectangle of
* pixels from a given texture.
@ -581,7 +698,7 @@ private:
void flushDrawBuffer();
static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
void setPaint(const GrPaint& paint, GrDrawTarget* target);
GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
@ -628,6 +745,42 @@ private:
const float* kernel,
int kernelWidth);
/**
* Flags to the internal read/write pixels funcs
*/
enum PixelOpsFlags {
kDontFlush_PixelOpsFlag = 0x1,
};
bool internalReadRenderTargetPixels(GrRenderTarget* target,
int left, int top,
int width, int height,
GrPixelConfig config, void* buffer,
size_t rowBytes, uint32_t flags);
void internalWriteRenderTargetPixels(GrRenderTarget* target,
int left, int top,
int width, int height,
GrPixelConfig, const void* buffer,
size_t rowBytes, uint32_t flags);
bool internalReadTexturePixels(GrTexture* texture,
int left, int top,
int width, int height,
GrPixelConfig config, void* buffer,
size_t rowBytes, uint32_t flags);
void internalWriteTexturePixels(GrTexture* texture,
int left, int top,
int width, int height,
GrPixelConfig config, const void* buffer,
size_t rowBytes, uint32_t flags);
// needed for access to internalWriteTexturePixels. TODO: make GrContext
// be a facade for an internal class. Then functions that are public on the
// internal class would have only be callable in src/gpu. The facade would
// only have to functions necessary for clients.
friend class GrAtlas;
// computes vertex layout bits based on the paint. If paint expresses
// a texture for a stage, the stage coords will be bound to postitions
// unless hasTexCoords[s]==true in which case stage s's input coords

View File

@ -77,6 +77,15 @@
* It is not extern "C".
* The GrGLInterface field fCallback specifies the function ptr and there is an
* additional field fCallbackData of type intptr_t for client data.
*
* GR_GL_RGBA_8888_PIXEL_OPS_SLOW: Set this to 1 if it is known that performing
* glReadPixels / glTex(Sub)Image with format=GL_RGBA, type=GL_UNISIGNED_BYTE is
* significantly slower than format=GL_BGRA, type=GL_UNISIGNED_BYTE.
*
* GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL: Set this to 1 if calling
* 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.
*/
#if !defined(GR_GL_LOG_CALLS)
@ -111,24 +120,20 @@
#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
#endif
#if !defined(GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL)
#define GR_GL_FULL_READPIXELS_FASTER_THAN_PARTIAL 0
#endif
#if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
#error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
#endif
////////////////////////////////////////////////////////////////////////////////
/**
* The following macros are used to staticlly configure the default
* GrGLInterface, but should not be used outside of the GrGLInterface
* scaffolding. Undefine here to prevent accidental use.
*/
#undef GR_SUPPORT_GLDESKTOP
#undef GR_SUPPORT_GLES1
#undef GR_SUPPORT_GLES2
#undef GR_SUPPORT_GLES
////////////////////////////////////////////////////////////////////////////////
#if GR_SCALAR_IS_FIXED
#define GrGLType GL_FIXED
#elif GR_SCALAR_IS_FLOAT
@ -150,16 +155,6 @@
#error "unknown GR_TEXT_SCALAR type"
#endif
// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA (except on
// Windows where we match GDI's order).
#ifndef GR_GL_32BPP_COLOR_FORMAT
#if GR_WIN32_BUILD || GR_LINUX_BUILD
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
#else
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_RGBA
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
struct GrGLInterface;
@ -224,14 +219,6 @@ extern void GrGLClearErr(const GrGLInterface* gl);
////////////////////////////////////////////////////////////////////////////////
/**
* GrGLResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
* this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
*/
extern void GrGLResetRowLength(const GrGLInterface*);
////////////////////////////////////////////////////////////////////////////////
/**
* Some drivers want the var-int arg to be zero-initialized on input.
*/

View File

@ -8,15 +8,18 @@
#ifndef GrGLConfig_chrome_DEFINED
#define GrGLConfig_chrome_DEFINED
// chrome always assumes BGRA
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
// 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

View File

@ -174,7 +174,9 @@
#define GR_GL_COLOR_CLEAR_VALUE 0x0C22
#define GR_GL_COLOR_WRITEMASK 0x0C23
#define GR_GL_UNPACK_ALIGNMENT 0x0CF5
#define GR_GL_UNPACK_FLIP_Y 0x9240
#define GR_GL_PACK_ALIGNMENT 0x0D05
#define GR_GL_PACK_REVERSE_ROW_ORDER 0x93A4
#define GR_GL_MAX_TEXTURE_SIZE 0x0D33
#define GR_GL_MAX_VIEWPORT_DIMS 0x0D3A
#define GR_GL_SUBPIXEL_BITS 0x0D50
@ -282,6 +284,9 @@
/* PixelFormat */
#define GR_GL_DEPTH_COMPONENT 0x1902
#define GR_GL_RED 0x1903
#define GR_GL_GREEN 0x1904
#define GR_GL_BLUE 0x1905
#define GR_GL_ALPHA 0x1906
#define GR_GL_RGB 0x1907
#define GR_GL_RGBA 0x1908
@ -289,6 +294,7 @@
#define GR_GL_LUMINANCE 0x1909
#define GR_GL_LUMINANCE_ALPHA 0x190A
#define GR_GL_PALETTE8_RGBA8 0x8B96
#define GR_GL_ALPHA8 0x803C
/* PixelType */
/* GL_UNSIGNED_BYTE */
@ -349,6 +355,8 @@
/* Pixel Mode / Transfer */
#define GR_GL_UNPACK_ROW_LENGTH 0x0CF2
#define GR_GL_PACK_ROW_LENGTH 0x0D02
/* TextureMagFilter */
#define GR_GL_NEAREST 0x2600
@ -362,11 +370,15 @@
#define GR_GL_NEAREST_MIPMAP_LINEAR 0x2702
#define GR_GL_LINEAR_MIPMAP_LINEAR 0x2703
/* TextureUsage */
#define GR_GL_FRAMEBUFFER_ATTACHMENT 0x93A3
/* TextureParameterName */
#define GR_GL_TEXTURE_MAG_FILTER 0x2800
#define GR_GL_TEXTURE_MIN_FILTER 0x2801
#define GR_GL_TEXTURE_WRAP_S 0x2802
#define GR_GL_TEXTURE_WRAP_T 0x2803
#define GR_GL_TEXTURE_USAGE 0x93A2
/* TextureTarget */
/* GL_TEXTURE_2D */
@ -422,6 +434,13 @@
#define GR_GL_CLAMP_TO_EDGE 0x812F
#define GR_GL_MIRRORED_REPEAT 0x8370
/* Texture Swizzle */
#define GR_GL_TEXTURE_SWIZZLE_R 0x8E42
#define GR_GL_TEXTURE_SWIZZLE_G 0x8E43
#define GR_GL_TEXTURE_SWIZZLE_B 0x8E44
#define GR_GL_TEXTURE_SWIZZLE_A 0x8E45
#define GR_GL_TEXTURE_SWIZZLE_RGBA 0x8E46
/* Texture mapping */
#define GR_GL_TEXTURE_ENV 0x2300
#define GR_GL_TEXTURE_ENV_MODE 0x2200
@ -614,6 +633,7 @@
#define GR_GL_RGB565 0x8D62
#define GR_GL_RGBA8 0x8058
#define GR_GL_RGB8 0x8051
#define GR_GL_BGRA8 0x93A1
#define GR_GL_SRGB 0x8C40
#define GR_GL_SRGB8 0x8C41
#define GR_GL_SRGB_ALPHA 0x8C42

View File

@ -111,8 +111,7 @@ typedef long GrGLsizeiptr;
enum GrGLBinding {
kDesktop_GrGLBinding = 0x01,
kES1_GrGLBinding = 0x02,
kES2_GrGLBinding = 0x04
kES2_GrGLBinding = 0x02
};
extern "C" {
@ -130,8 +129,6 @@ extern "C" {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearProc)(GrGLbitfield mask);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearColorProc)(GrGLclampf red, GrGLclampf green, GrGLclampf blue, GrGLclampf alpha);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClearStencilProc)(GrGLint s);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLClientActiveTextureProc)(GrGLenum texture);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColor4ubProc)(GrGLubyte red, GrGLubyte green, GrGLubyte blue, GrGLubyte alpha);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColorMaskProc)(GrGLboolean red, GrGLboolean green, GrGLboolean blue, GrGLboolean alpha);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLColorPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLCompileShaderProc)(GrGLuint shader);
@ -146,14 +143,12 @@ extern "C" {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDeleteTexturesProc)(GrGLsizei n, const GrGLuint* textures);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDepthMaskProc)(GrGLboolean flag);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableProc)(GrGLenum cap);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableClientStateProc)(GrGLenum array);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDisableVertexAttribArrayProc)(GrGLuint index);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawArraysProc)(GrGLenum mode, GrGLint first, GrGLsizei count);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawBufferProc)(GrGLenum mode);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawBuffersProc)(GrGLsizei n, const GrGLenum* bufs);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableProc)(GrGLenum cap);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableClientStateProc)(GrGLenum cap);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEnableVertexAttribArrayProc)(GrGLuint index);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLEndQueryProc)(GrGLenum target);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLFinishProc)();
@ -179,15 +174,11 @@ extern "C" {
typedef GrGLint (GR_GL_FUNCTION_TYPE *GrGLGetUniformLocationProc)(GrGLuint program, const char* name);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLineWidthProc)(GrGLfloat width);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLinkProgramProc)(GrGLuint program);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLLoadMatrixfProc)(const GrGLfloat* m);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLMatrixModeProc)(GrGLenum mode);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPixelStoreiProc)(GrGLenum pname, GrGLint param);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLPointSizeProc)(GrGLfloat size);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLQueryCounterProc)(GrGLuint id, GrGLenum target);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadBufferProc)(GrGLenum src);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLScissorProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLShadeModelProc)(GrGLenum mode);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLShaderSourceProc)(GrGLuint shader, GrGLsizei count, const char** str, const GrGLint* length);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncProc)(GrGLenum func, GrGLint ref, GrGLuint mask);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilFuncSeparateProc)(GrGLenum face, GrGLenum func, GrGLint ref, GrGLuint mask);
@ -195,10 +186,9 @@ extern "C" {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilMaskSeparateProc)(GrGLenum face, GrGLuint mask);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpProc)(GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLStencilOpSeparateProc)(GrGLenum face, GrGLenum fail, GrGLenum zfail, GrGLenum zpass);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexCoordPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexEnviProc)(GrGLenum target, GrGLenum pname, GrGLint param);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexImage2DProc)(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexParameteriProc)(GrGLenum target, GrGLenum pname, GrGLint param);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexStorage2DProc)(GrGLenum target, GrGLsizei levels, GrGLenum internalformat, GrGLsizei width, GrGLsizei height);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fProc)(GrGLint location, GrGLfloat v0);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1iProc)(GrGLint location, GrGLint v0);
@ -222,7 +212,6 @@ extern "C" {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUseProgramProc)(GrGLuint program);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLViewportProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height);
// FBO Extension Functions
@ -278,35 +267,18 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLInterface();
bool validate(GrEngine engine) const;
bool validate() const;
bool supportsDesktop() const {
return 0 != (kDesktop_GrGLBinding & fBindingsExported);
}
bool supportsES1() const {
return 0 != (kES1_GrGLBinding & fBindingsExported);
}
bool supportsES2() const {
return 0 != (kES2_GrGLBinding & fBindingsExported);
}
bool supportsES() const {
return 0 != ((kES1_GrGLBinding | kES2_GrGLBinding) &
fBindingsExported);
}
// Indicator variable specifying the type of GL implementation
// exported: GLES{1|2} or Desktop.
GrGLBinding fBindingsExported;
/// Does this GL support NPOT textures on FBOs?
/// boolean value, or kProbe_GrGLCapability to probe (slowly) at context creation.
int fNPOTRenderTargetSupport;
/// Some GL implementations (PowerVR SGX devices like the iPhone 4)
/// have restrictions on the size of small render targets.
/// kProbe_GrGLCapability to probe (slowly) at context creation.
int fMinRenderTargetHeight;
int fMinRenderTargetWidth;
GrGLActiveTextureProc fActiveTexture;
GrGLAttachShaderProc fAttachShader;
GrGLBeginQueryProc fBeginQuery;
@ -321,8 +293,6 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLClearProc fClear;
GrGLClearColorProc fClearColor;
GrGLClearStencilProc fClearStencil;
GrGLClientActiveTextureProc fClientActiveTexture;
GrGLColor4ubProc fColor4ub;
GrGLColorMaskProc fColorMask;
GrGLColorPointerProc fColorPointer;
GrGLCompileShaderProc fCompileShader;
@ -337,14 +307,12 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLDeleteTexturesProc fDeleteTextures;
GrGLDepthMaskProc fDepthMask;
GrGLDisableProc fDisable;
GrGLDisableClientStateProc fDisableClientState;
GrGLDisableVertexAttribArrayProc fDisableVertexAttribArray;
GrGLDrawArraysProc fDrawArrays;
GrGLDrawBufferProc fDrawBuffer;
GrGLDrawBuffersProc fDrawBuffers;
GrGLDrawElementsProc fDrawElements;
GrGLEnableProc fEnable;
GrGLEnableClientStateProc fEnableClientState;
GrGLEnableVertexAttribArrayProc fEnableVertexAttribArray;
GrGLEndQueryProc fEndQuery;
GrGLFinishProc fFinish;
@ -370,15 +338,11 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLGetUniformLocationProc fGetUniformLocation;
GrGLLineWidthProc fLineWidth;
GrGLLinkProgramProc fLinkProgram;
GrGLLoadMatrixfProc fLoadMatrixf;
GrGLMatrixModeProc fMatrixMode;
GrGLPixelStoreiProc fPixelStorei;
GrGLPointSizeProc fPointSize;
GrGLQueryCounterProc fQueryCounter;
GrGLReadBufferProc fReadBuffer;
GrGLReadPixelsProc fReadPixels;
GrGLScissorProc fScissor;
GrGLShadeModelProc fShadeModel;
GrGLShaderSourceProc fShaderSource;
GrGLStencilFuncProc fStencilFunc;
GrGLStencilFuncSeparateProc fStencilFuncSeparate;
@ -386,11 +350,10 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLStencilMaskSeparateProc fStencilMaskSeparate;
GrGLStencilOpProc fStencilOp;
GrGLStencilOpSeparateProc fStencilOpSeparate;
GrGLTexCoordPointerProc fTexCoordPointer;
GrGLTexEnviProc fTexEnvi;
GrGLTexImage2DProc fTexImage2D;
GrGLTexParameteriProc fTexParameteri;
GrGLTexSubImage2DProc fTexSubImage2D;
GrGLTexStorage2DProc fTexStorage2D;
GrGLUniform1fProc fUniform1f;
GrGLUniform1iProc fUniform1i;
GrGLUniform1fvProc fUniform1fv;
@ -413,7 +376,6 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLUseProgramProc fUseProgram;
GrGLVertexAttrib4fvProc fVertexAttrib4fv;
GrGLVertexAttribPointerProc fVertexAttribPointer;
GrGLVertexPointerProc fVertexPointer;
GrGLViewportProc fViewport;
// FBO Extension Functions
@ -451,9 +413,6 @@ struct GR_API GrGLInterface : public GrRefCnt {
GrGLInterfaceCallbackData fCallbackData;
#endif
private:
bool validateShaderFunctions() const;
bool validateFixedFunctions() const;
};
#endif

View File

@ -33,11 +33,13 @@ public:
GrBlendCoeff fDstBlendCoeff;
bool fAntiAlias;
bool fDither;
bool fColorMatrixEnabled;
GrColor fColor;
GrColor fColorFilterColor;
SkXfermode::Mode fColorFilterXfermode;
float fColorMatrix[20];
void setTexture(int i, GrTexture* texture) {
GrAssert((unsigned)i < kMaxTextures);
@ -51,14 +53,14 @@ public:
return fTextures[i];
}
GrSamplerState* getTextureSampler(int i) {
GrSamplerState* textureSampler(int i) {
GrAssert((unsigned)i < kMaxTextures);
return fTextureSamplers + i;
}
const GrSamplerState* getTextureSampler(int i) const {
const GrSamplerState& getTextureSampler(int i) const {
GrAssert((unsigned)i < kMaxTextures);
return fTextureSamplers + i;
return fTextureSamplers[i];
}
// The mask can be alpha-only or per channel. It is applied
@ -77,14 +79,14 @@ public:
// mask's sampler matrix is always applied to the positions
// (i.e. no explicit texture coordinates)
GrSamplerState* getMaskSampler(int i) {
GrSamplerState* maskSampler(int i) {
GrAssert((unsigned)i < kMaxMasks);
return fMaskSamplers + i;
}
const GrSamplerState* getMaskSampler(int i) const {
const GrSamplerState& getMaskSampler(int i) const {
GrAssert((unsigned)i < kMaxMasks);
return fMaskSamplers + i;
return fMaskSamplers[i];
}
// pre-concats sampler matrices for non-NULL textures and masks
@ -127,6 +129,8 @@ public:
fColorFilterColor = paint.fColorFilterColor;
fColorFilterXfermode = paint.fColorFilterXfermode;
memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
fColorMatrixEnabled = paint.fColorMatrixEnabled;
for (int i = 0; i < kMaxTextures; ++i) {
GrSafeUnref(fTextures[i]);
@ -165,6 +169,8 @@ public:
void resetColorFilter() {
fColorFilterXfermode = SkXfermode::kDst_Mode;
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
memset(fColorMatrix, 0, sizeof(fColorMatrix));
fColorMatrixEnabled = false;
}
bool hasTexture() const {
@ -239,14 +245,14 @@ private:
void resetTextures() {
for (int i = 0; i < kMaxTextures; ++i) {
this->setTexture(i, NULL);
fTextureSamplers[i].setClampNoFilter();
fTextureSamplers[i].reset();
}
}
void resetMasks() {
for (int i = 0; i < kMaxMasks; ++i) {
this->setMask(i, NULL);
fMaskSamplers[i].setClampNoFilter();
fMaskSamplers[i].reset();
}
}
};

View File

@ -43,20 +43,6 @@ public:
*/
int height() const { return fHeight; }
/**
* Retrieves the allocated width. It may differ from width for
* NPOT or min-RT size reasons.
* @return allocated width in pixels
*/
int allocatedWidth() const { return fAllocatedWidth; }
/**
* Retrieves the allocated height. It may differ from height for
* NPOT or min-RT size reasons.
* @return allocated height in pixels
*/
int allocatedHeight() const { return fAllocatedHeight; }
/**
* @return the pixel config. Can be kUnknown_GrPixelConfig
* if client asked us to render to a target that has a pixel
@ -137,12 +123,29 @@ public:
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*
* @return true if the read succeeded, false if not. The read can fail
* because of a unsupported pixel config.
* because of an unsupported pixel config.
*/
bool readPixels(int left, int top, int width, int height,
GrPixelConfig config, void* buffer);
GrPixelConfig config, void* buffer, size_t rowBytes);
/**
* Copy the src pixels [buffer, rowbytes, pixelconfig] into the render
* target at the specified rectangle.
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param buffer memory to read the rectangle from.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*/
void writePixels(int left, int top, int width, int height,
GrPixelConfig config, const void* buffer, size_t rowBytes);
// a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
// 0 in GL), or be unresolvable because the client didn't give us the
@ -165,8 +168,6 @@ protected:
GrTexture* texture,
int width,
int height,
int allocatedWidth,
int allocatedHeight,
GrPixelConfig config,
int sampleCnt)
: INHERITED(gpu)
@ -174,8 +175,6 @@ protected:
, fTexture(texture)
, fWidth(width)
, fHeight(height)
, fAllocatedWidth(allocatedWidth)
, fAllocatedHeight(allocatedHeight)
, fConfig(config)
, fSampleCnt(sampleCnt) {
fResolveRect.setLargestInverted();
@ -197,8 +196,6 @@ private:
GrTexture* fTexture; // not ref'ed
int fWidth;
int fHeight;
int fAllocatedWidth;
int fAllocatedHeight;
GrPixelConfig fConfig;
int fSampleCnt;
GrIRect fResolveRect;

View File

@ -13,6 +13,7 @@
#include "GrRefCnt.h"
class GrGpu;
class GrContext;
class GrResource : public GrRefCnt {
public:
@ -55,6 +56,15 @@ public:
*/
virtual size_t sizeInBytes() const = 0;
/**
* Retrieves the context that owns the resource. Note that it is possible
* for this to return NULL. When resources have been release()ed or
* abandon()ed they no longer have an unknowning context. Destroying a
* GrContext automatically releases all its resources.
*/
const GrContext* getContext() const;
GrContext* getContext();
protected:
virtual void onRelease() = 0;

View File

@ -38,7 +38,9 @@ public:
/**
* Apply a separable convolution kernel.
*/
kConvolution_Filter
kConvolution_Filter,
kDefault_Filter = kNearest_Filter
};
/**
@ -68,6 +70,8 @@ public:
kRadial_SampleMode, //!< treat as radial gradient
kRadial2_SampleMode, //!< treat as 2-point radial gradient
kSweep_SampleMode, //!< treat as sweep gradient
kDefault_SampleMode = kNormal_SampleMode
};
/**
@ -77,7 +81,9 @@ public:
enum WrapMode {
kClamp_WrapMode,
kRepeat_WrapMode,
kMirror_WrapMode
kMirror_WrapMode,
kDefault_WrapMode = kClamp_WrapMode
};
/**
@ -88,57 +94,7 @@ public:
: fRadial2CenterX1()
, fRadial2Radius0()
, fRadial2PosRoot() {
this->setClampNoFilter();
}
explicit GrSamplerState(Filter filter)
: fRadial2CenterX1()
, fRadial2Radius0()
, fRadial2PosRoot() {
fWrapX = kClamp_WrapMode;
fWrapY = kClamp_WrapMode;
fSampleMode = kNormal_SampleMode;
fFilter = filter;
fMatrix.setIdentity();
fTextureDomain.setEmpty();
}
GrSamplerState(WrapMode wx, WrapMode wy, Filter filter)
: fRadial2CenterX1()
, fRadial2Radius0()
, fRadial2PosRoot() {
fWrapX = wx;
fWrapY = wy;
fSampleMode = kNormal_SampleMode;
fFilter = filter;
fMatrix.setIdentity();
fTextureDomain.setEmpty();
}
GrSamplerState(WrapMode wx, WrapMode wy,
const GrMatrix& matrix, Filter filter)
: fRadial2CenterX1()
, fRadial2Radius0()
, fRadial2PosRoot() {
fWrapX = wx;
fWrapY = wy;
fSampleMode = kNormal_SampleMode;
fFilter = filter;
fMatrix = matrix;
fTextureDomain.setEmpty();
}
GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample,
const GrMatrix& matrix, Filter filter)
: fRadial2CenterX1()
, fRadial2Radius0()
, fRadial2PosRoot() {
fWrapX = wx;
fWrapY = wy;
fSampleMode = sample;
fMatrix = matrix;
fFilter = filter;
fTextureDomain.setEmpty();
this->reset();
}
WrapMode getWrapX() const { return fWrapX; }
@ -151,6 +107,7 @@ public:
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 {
return kRadial_SampleMode == fSampleMode ||
@ -163,11 +120,10 @@ public:
void setSampleMode(SampleMode mode) { fSampleMode = mode; }
/**
* Sets the sampler's matrix. See SampleMode for explanation of
* Access the sampler's matrix. See SampleMode for explanation of
* relationship between the matrix and sample mode.
* @param matrix the matrix to set
*/
void setMatrix(const GrMatrix& matrix) { fMatrix = matrix; }
GrMatrix* matrix() { return &fMatrix; }
/**
* Sets the sampler's texture coordinate domain to a
@ -176,6 +132,12 @@ public:
*/
void setTextureDomain(const GrRect& textureDomain) { fTextureDomain = textureDomain; }
/**
* Swaps the R and B components when reading from the texture. Has no effect
* if the texture is alpha only.
*/
void setRAndBSwap(bool swap) { fSwapRAndB = swap; }
/**
* Multiplies the current sampler matrix a matrix
*
@ -194,18 +156,31 @@ public:
*/
void setFilter(Filter filter) { fFilter = filter; }
void setClampNoFilter() {
fWrapX = kClamp_WrapMode;
fWrapY = kClamp_WrapMode;
fSampleMode = kNormal_SampleMode;
fFilter = kNearest_Filter;
fMatrix.setIdentity();
void reset(WrapMode wrapXAndY,
Filter filter,
const GrMatrix& matrix) {
fWrapX = wrapXAndY;
fWrapY = wrapXAndY;
fSampleMode = kDefault_SampleMode;
fFilter = filter;
fMatrix = matrix;
fTextureDomain.setEmpty();
fSwapRAndB = false;
}
void reset(WrapMode wrapXAndY,
Filter filter) {
this->reset(wrapXAndY, filter, GrMatrix::I());
}
void reset(const GrMatrix& matrix) {
this->reset(kDefault_WrapMode, kDefault_Filter, matrix);
}
void reset() {
this->reset(kDefault_WrapMode, kDefault_Filter, GrMatrix::I());
}
GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
bool isRadial2PosRoot() const { return fRadial2PosRoot; }
bool isRadial2PosRoot() const { return SkToBool(fRadial2PosRoot); }
// do the radial gradient params lead to a linear (rather than quadratic)
// equation.
bool radial2IsDegenerate() const { return GR_Scalar1 == fRadial2CenterX1; }
@ -236,29 +211,24 @@ public:
}
}
static const GrSamplerState& ClampNoFilter() {
return gClampNoFilter;
}
private:
WrapMode fWrapX;
WrapMode fWrapY;
SampleMode fSampleMode;
Filter fFilter;
WrapMode fWrapX : 8;
WrapMode fWrapY : 8;
SampleMode fSampleMode : 8;
Filter fFilter : 8;
GrMatrix fMatrix;
bool fSwapRAndB;
GrRect fTextureDomain;
// these are undefined unless fSampleMode == kRadial2_SampleMode
GrScalar fRadial2CenterX1;
GrScalar fRadial2Radius0;
bool fRadial2PosRoot;
SkBool8 fRadial2PosRoot;
// These are undefined unless fFilter == kConvolution_Filter
int fKernelWidth;
float fKernel[MAX_KERNEL_WIDTH];
uint8_t fKernelWidth;
float fImageIncrement[2];
static const GrSamplerState gClampNoFilter;
float fKernel[MAX_KERNEL_WIDTH];
};
#endif

View File

@ -32,20 +32,6 @@ public:
*/
int height() const { return fHeight; }
/**
* Retrieves the allocated width. It may differ from width for
* NPOT or min-RT size reasons.
* @return allocated width in texels
*/
int allocatedWidth() const { return fAllocatedWidth; }
/**
* Retrieves the allocated height. It may differ from height for
* NPOT or min-RT size reasons.
* @return allocated height in texels
*/
int allocatedHeight() const { return fAllocatedHeight; }
/**
* Convert from texels to normalized texture coords for POT textures
* only.
@ -64,44 +50,41 @@ public:
* Approximate number of bytes used by the texture
*/
virtual size_t sizeInBytes() const {
return (size_t) fAllocatedWidth *
fAllocatedHeight *
GrBytesPerPixel(fConfig);
return (size_t) fWidth * fHeight * GrBytesPerPixel(fConfig);
}
/**
* Updates a subrectangle of texels in the texture.
*
* @param x left edge of rectangle to update
* @param y top edge of rectangle to update
* @param width width of rectangle to update
* @param height height of rectangle to update
* @param srcData width*height texels of data in same format that was
* used at texture creation.
* @param rowBytes number of bytes per row in srcData, 0 means rows are
* packed
*/
virtual void uploadTextureData(int x,
int y,
int width,
int height,
const void* srcData,
size_t rowBytes) = 0;
/**
* Reads a rectangle of pixels from the texture.
* Read a rectangle of pixels from the texture.
* @param left left edge of the rectangle to read (inclusive)
* @param top top edge of the rectangle to read (inclusive)
* @param width width of rectangle to read in pixels.
* @param height height of rectangle to read in pixels.
* @param config the pixel config of the destination buffer
* @param buffer memory to read the rectangle into.
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*
* @return true if the read succeeded, false if not. The read can fail
* because of a unsupported pixel config.
*/
bool readPixels(int left, int top, int width, int height,
GrPixelConfig config, void* buffer);
GrPixelConfig config, void* buffer,
size_t rowBytes);
/**
* Writes a rectangle of pixels to the texture.
* @param left left edge of the rectangle to write (inclusive)
* @param top top edge of the rectangle to write (inclusive)
* @param width width of rectangle to write in pixels.
* @param height height of rectangle to write in pixels.
* @param config the pixel config of the source buffer
* @param buffer memory to read pixels from
* @param rowBytes number of bytes bewtween consecutive rows. Zero
* means rows are tightly packed.
*/
void writePixels(int left, int top, int width, int height,
GrPixelConfig config, const void* buffer,
size_t rowBytes);
/**
* Retrieves the render target underlying this texture that can be passed to
@ -141,15 +124,11 @@ protected:
GrTexture(GrGpu* gpu,
int width,
int height,
int allocatedWidth,
int allocatedHeight,
GrPixelConfig config)
: INHERITED(gpu)
, fRenderTarget(NULL)
, fWidth(width)
, fHeight(height)
, fAllocatedWidth(allocatedWidth)
, fAllocatedHeight(allocatedHeight)
, fConfig(config) {
// only make sense if alloc size is pow2
fShiftFixedX = 31 - Gr_clz(fWidth);
@ -166,8 +145,6 @@ protected:
private:
int fWidth;
int fHeight;
int fAllocatedWidth;
int fAllocatedHeight;
// these two shift a fixed-point value into normalized coordinates
// for this texture if the texture is power of two sized.

View File

@ -55,7 +55,7 @@
* n is already a multiple of 4
*/
#define GrALIGN4(n) SkAlign4(n)
#define GrIsALIGN4(n) (((n) & 3) == 0)
#define GrIsALIGN4(n) SkIsAlign4(n)
template <typename T> const T& GrMin(const T& a, const T& b) {
return (a < b) ? a : b;
@ -268,17 +268,116 @@ static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
/**
* Pixel configurations.
*
* Unpremultiplied configs are intended for converting pixel data in and out
* from skia. Surfaces with these configs have limited support. As an input
* (GrPaint texture) the corresponding GrSamplerState must have its filter set
* to kNearest_Filter. Otherwise, the draw will fail. When the render target
* has an unpremultiplied config draws must use blend coeffs 1,0 (AKA src-mode).
* Other coeffs will cause the draw to fail.
*/
enum GrPixelConfig {
kUnknown_GrPixelConfig,
kAlpha_8_GrPixelConfig,
kIndex_8_GrPixelConfig,
kRGB_565_GrPixelConfig,
kRGBA_4444_GrPixelConfig, //!< premultiplied
kRGBA_8888_GrPixelConfig, //!< premultiplied
kRGBX_8888_GrPixelConfig, //!< treat the alpha channel as opaque
/**
* Premultiplied
*/
kRGBA_4444_GrPixelConfig,
/**
* Premultiplied. Byte order is r,g,b,a
*/
kRGBA_8888_PM_GrPixelConfig,
/**
* Unpremultiplied. Byte order is r,g,b,a
*/
kRGBA_8888_UPM_GrPixelConfig,
/**
* Premultiplied. Byte order is b,g,r,a
*/
kBGRA_8888_PM_GrPixelConfig,
/**
* Unpremultiplied. Byte order is b,g,r,a
*/
kBGRA_8888_UPM_GrPixelConfig,
};
// Aliases for pixel configs that match skia's byte order
#ifndef SK_CPU_LENDIAN
#error "Skia gpu currently assumes little endian"
#endif
#if 24 == SK_A32_SHIFT && 16 == SK_R32_SHIFT && \
8 == SK_G32_SHIFT && 0 == SK_B32_SHIFT
static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kBGRA_8888_PM_GrPixelConfig;
static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kBGRA_8888_UPM_GrPixelConfig;
#elif 24 == SK_A32_SHIFT && 16 == SK_B32_SHIFT && \
8 == SK_G32_SHIFT && 0 == SK_R32_SHIFT
static const GrPixelConfig kSkia8888_PM_GrPixelConfig = kRGBA_8888_PM_GrPixelConfig;
static const GrPixelConfig kSkia8888_UPM_GrPixelConfig = kRGBA_8888_UPM_GrPixelConfig;
#else
#error "SK_*32_SHIFT values must correspond to GL_BGRA or GL_RGBA format."
#endif
// WebKit is relying on this old name for the native skia PM config. This will
// be deleted ASAP because it is so similar to kRGBA_PM_8888_GrPixelConfig but
// has a different interpretation when skia is compiled BGRA.
static const GrPixelConfig kRGBA_8888_GrPixelConfig = kSkia8888_PM_GrPixelConfig;
// Returns true if the pixel config has 8bit r,g,b,a components in that byte
// order
static inline bool GrPixelConfigIsRGBA8888(GrPixelConfig config) {
switch (config) {
case kRGBA_8888_PM_GrPixelConfig:
case kRGBA_8888_UPM_GrPixelConfig:
return true;
default:
return false;
}
}
// Returns true if the pixel config has 8bit b,g,r,a components in that byte
// order
static inline bool GrPixelConfigIsBGRA8888(GrPixelConfig config) {
switch (config) {
case kBGRA_8888_PM_GrPixelConfig:
case kBGRA_8888_UPM_GrPixelConfig:
return true;
default:
return false;
}
}
// Returns true if the pixel config is 32 bits per pixel
static inline bool GrPixelConfigIs32Bit(GrPixelConfig config) {
switch (config) {
case kRGBA_8888_PM_GrPixelConfig:
case kRGBA_8888_UPM_GrPixelConfig:
case kBGRA_8888_PM_GrPixelConfig:
case kBGRA_8888_UPM_GrPixelConfig:
return true;
default:
return false;
}
}
// Takes a config and returns the equivalent config with the R and B order
// swapped if such a config exists. Otherwise, kUnknown_GrPixelConfig
static inline GrPixelConfig GrPixelConfigSwapRAndB(GrPixelConfig config) {
switch (config) {
case kBGRA_8888_PM_GrPixelConfig:
return kRGBA_8888_PM_GrPixelConfig;
case kBGRA_8888_UPM_GrPixelConfig:
return kRGBA_8888_UPM_GrPixelConfig;
case kRGBA_8888_PM_GrPixelConfig:
return kBGRA_8888_PM_GrPixelConfig;
case kRGBA_8888_UPM_GrPixelConfig:
return kBGRA_8888_UPM_GrPixelConfig;
default:
return kUnknown_GrPixelConfig;
}
}
static inline size_t GrBytesPerPixel(GrPixelConfig config) {
switch (config) {
case kAlpha_8_GrPixelConfig:
@ -287,8 +386,10 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
return 2;
case kRGBA_8888_GrPixelConfig:
case kRGBX_8888_GrPixelConfig:
case kRGBA_8888_PM_GrPixelConfig:
case kRGBA_8888_UPM_GrPixelConfig:
case kBGRA_8888_PM_GrPixelConfig:
case kBGRA_8888_UPM_GrPixelConfig:
return 4;
default:
return 0;
@ -298,7 +399,20 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
switch (config) {
case kRGB_565_GrPixelConfig:
case kRGBX_8888_GrPixelConfig:
return true;
default:
return false;
}
}
/**
* Premultiplied alpha is the usual for skia. Therefore, configs that are
* ambiguous (alpha-only or color-only) are considered premultiplied.
*/
static inline bool GrPixelConfigIsUnpremultiplied(GrPixelConfig config) {
switch (config) {
case kRGBA_8888_UPM_GrPixelConfig:
case kBGRA_8888_UPM_GrPixelConfig:
return true;
default:
return false;
@ -376,7 +490,7 @@ struct GrTextureDesc {
* Format of source data of the texture. Not guaraunteed to be the same as
* internal format used by 3D API.
*/
GrPixelConfig fFormat;
GrPixelConfig fConfig;
};
/**
@ -499,6 +613,99 @@ enum GrConvexHint {
///////////////////////////////////////////////////////////////////////////////
// opaque type for 3D API object handles
typedef intptr_t GrPlatform3DObject;
/**
* Gr can wrap an existing texture created by the client with a GrTexture
* object. The client is responsible for ensuring that the texture lives at
* least as long as the GrTexture object wrapping it. We require the client to
* explicitly provide information about the texture, such as width, height,
* and pixel config, rather than querying the 3D APIfor these values. We expect
* these to be immutable even if the 3D API doesn't require this (OpenGL).
*
* Textures that are also render targets are supported as well. Gr will manage
* any ancillary 3D API (stencil buffer, FBO id, etc) objects necessary for
* Gr to draw into the render target. To access the render target object
* call GrTexture::asRenderTarget().
*
* If in addition to the render target flag, the caller also specifies a sample
* count Gr will create an MSAA buffer that resolves into the texture. Gr auto-
* resolves when it reads from the texture. The client can explictly resolve
* using the GrRenderTarget interface.
*/
enum GrPlatformTextureFlags {
/**
* No flags enabled
*/
kNone_GrPlatformTextureFlag = 0x0,
/**
* Indicates that the texture is also a render target, and thus should have
* a GrRenderTarget object.
*
* D3D (future): client must have created the texture with flags that allow
* it to be used as a render target.
*/
kRenderTarget_GrPlatformTextureFlag = 0x1,
};
GR_MAKE_BITFIELD_OPS(GrPlatformTextureFlags)
struct GrPlatformTextureDesc {
GrPlatformTextureDesc() { memset(this, 0, sizeof(*this)); }
GrPlatformTextureFlags fFlags;
int fWidth; //<! width in pixels
int fHeight; //<! height in pixels
GrPixelConfig fConfig; //<! color format
/**
* If the render target flag is set and sample count is greater than 0
* then Gr will create an MSAA buffer that resolves to the texture.
*/
int fSampleCnt;
/**
* Handle to the 3D API object.
* OpenGL: Texture ID.
*/
GrPlatform3DObject fTextureHandle;
};
///////////////////////////////////////////////////////////////////////////////
/**
* Gr can wrap an existing render target created by the client in the 3D API
* with a GrRenderTarget object. The client is responsible for ensuring that the
* underlying 3D API object lives at least as long as the GrRenderTarget object
* wrapping it. We require the client to explicitly provide information about
* the target, such as width, height, and pixel config rather than querying the
* 3D API for these values. We expect these properties to be immutable even if
* the 3D API doesn't require this (OpenGL).
*/
struct GrPlatformRenderTargetDesc {
GrPlatformRenderTargetDesc() { memset(this, 0, sizeof(*this)); }
int fWidth; //<! width in pixels
int fHeight; //<! height in pixels
GrPixelConfig fConfig; //<! color format
/**
* The number of samples per pixel. Gr uses this to influence decisions
* about applying other forms of antialiasing.
*/
int fSampleCnt;
/**
* Number of bits of stencil per-pixel.
*/
int fStencilBits;
/**
* Handle to the 3D API object.
* OpenGL: FBO ID
*/
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.
@ -532,12 +739,6 @@ enum GrPlatformRenderTargetFlags {
GR_MAKE_BITFIELD_OPS(GrPlatformRenderTargetFlags)
// opaque type for 3D API object handles
typedef intptr_t GrPlatform3DObject;
/**
* Description of platform surface to create. See below for GL example.
*/
struct GrPlatformSurfaceDesc {
GrPlatformSurfaceType fSurfaceType; // type of surface to create
/**
@ -618,7 +819,7 @@ struct GrPlatformSurfaceDesc {
* renderTargetTextureDesc.fRenderTargetFlags = kGrCanResolve_GrPlatformRenderTargetFlagBit;
* renderTargetTextureDesc.fWidth = W;
* renderTargetTextureDesc.fHeight = H;
* renderTargetTextureDesc.fConfig = kRGBA_8888_GrPixelConfig
* renderTargetTextureDesc.fConfig = kSkia8888_PM_GrPixelConfig
* renderTargetTextureDesc.fStencilBits = 8;
* renderTargetTextureDesc.fSampleCnt = S;
* renderTargetTextureDesc.fPlatformTexture = textureID;

View File

@ -21,27 +21,12 @@
#define GR_DEBUG 1
#endif
/*
* The default 32bit pixel config for texture upload is GL_RGBA on all
* platforms except on Windows where it is GL_BGRA. If your bitmaps map to a
* different GL enum, specify that with this define. For portability use
* GR_BGRA rather than GL_BGRA for platforms where this format is an
* extension.
*/
//#define GR_GL_32BPP_COLOR_FORMAT GL_RGBA
/*
* To diagnose texture cache performance, define this to 1 if you want to see
* a log statement everytime we upload an image to create a texture.
*/
//#define GR_DUMP_TEXTURE_UPLOAD 1
/*
* To log all GL calls define this. Can be turned on and off at runtime by
* gPrintGL global variable.
*/
//#define GR_GL_LOG_CALLS 1
/*
* When drawing rects this causes Ganesh to use a vertex buffer containing
* a unit square that is positioned by a matrix. Enable on systems where
@ -63,11 +48,6 @@
*/
//#define GR_GEOM_BUFFER_LOCK_THRESHOLD (1<<15)
///////////////////////////////////////////////////////////////////////////////
/*
* temporary flags (may go away soon)
*/
///////////////////////////////////////////////////////////////////////////////
// Decide Ganesh types

View File

@ -59,52 +59,50 @@ public:
* The canvas parameter must be a SkGpuCanvas
*/
virtual void gainFocus(SkCanvas*, const SkMatrix&, const SkRegion&,
const SkClipStack& clipStack);
const SkClipStack& clipStack) SK_OVERRIDE;
virtual SkGpuRenderTarget* accessRenderTarget() {
return (SkGpuRenderTarget*)fRenderTarget;
}
virtual SkGpuRenderTarget* accessRenderTarget() SK_OVERRIDE;
// overrides from SkDevice
virtual void clear(SkColor color);
virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
virtual void writePixels(const SkBitmap& bitmap, int x, int y);
virtual void clear(SkColor color) SK_OVERRIDE;
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
SkCanvas::Config8888 config8888) SK_OVERRIDE;
virtual void setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
const SkClipStack&);
const SkClipStack&) SK_OVERRIDE;
virtual void drawPaint(const SkDraw&, const SkPaint& paint);
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
const SkPoint[], const SkPaint& paint);
const SkPoint[], const SkPaint& paint) SK_OVERRIDE;
virtual void drawRect(const SkDraw&, const SkRect& r,
const SkPaint& paint);
const SkPaint& paint) SK_OVERRIDE;
virtual void drawPath(const SkDraw&, const SkPath& path,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable);
bool pathIsMutable) SK_OVERRIDE;
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
const SkIRect* srcRectOrNull,
const SkMatrix& matrix, const SkPaint& paint);
const SkMatrix&, const SkPaint&) SK_OVERRIDE;
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
int x, int y, const SkPaint& paint);
virtual void drawText(const SkDraw&, const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint);
SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], SkScalar constY,
int scalarsPerPos, const SkPaint& paint);
int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
const SkPaint&) SK_OVERRIDE;
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);
const SkPaint&) SK_OVERRIDE;
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
const SkPaint&);
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*);
const SkPaint&) SK_OVERRIDE;
virtual bool filterTextFlags(const SkPaint&, TextFlags*) SK_OVERRIDE;
virtual void flush() { fContext->flush(false); }
virtual void flush();
/**
* Make's this device's rendertarget current in the underlying 3D API.
@ -112,6 +110,10 @@ public:
*/
virtual void makeRenderTargetCurrent();
virtual bool filterImage(SkImageFilter*, const SkBitmap& src,
const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
protected:
typedef GrContext::TextureCacheEntry TexCache;
enum TexType {
@ -120,8 +122,10 @@ protected:
kSaveLayerDeviceRenderTarget_TexType
};
TexCache lockCachedTexture(const SkBitmap& bitmap,
const GrSamplerState& sampler,
const GrSamplerState* sampler,
TexType type = kBitmap_TexType);
bool isBitmapInTextureCache(const SkBitmap& bitmap,
const GrSamplerState& sampler) const;
void unlockCachedTexture(TexCache);
class SkAutoCachedTexture {
@ -129,11 +133,11 @@ protected:
SkAutoCachedTexture();
SkAutoCachedTexture(SkGpuDevice* device,
const SkBitmap& bitmap,
const GrSamplerState& sampler,
const GrSamplerState* sampler,
GrTexture** texture);
~SkAutoCachedTexture();
GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState&);
GrTexture* set(SkGpuDevice*, const SkBitmap&, const GrSamplerState*);
private:
SkGpuDevice* fDevice;
@ -141,6 +145,12 @@ protected:
};
friend class SkAutoTexCache;
// overrides from SkDevice
virtual bool onReadPixels(const SkBitmap& bitmap,
int x, int y,
SkCanvas::Config8888 config8888) SK_OVERRIDE;
private:
GrContext* fContext;
@ -190,6 +200,10 @@ private:
bool bindDeviceAsTexture(GrPaint* paint);
void prepareRenderTarget(const SkDraw&);
bool shouldTileBitmap(const SkBitmap& bitmap,
const GrSamplerState& sampler,
const SkIRect* srcRectPtr,
int* tileSize) const;
void internalDrawBitmap(const SkDraw&, const SkBitmap&,
const SkIRect&, const SkMatrix&, GrPaint* grPaint);

View File

@ -14,7 +14,7 @@
#include <stddef.h>
// Gr headers
#include "GrConfig.h"
#include "GrTypes.h"
#include "GrContext.h"
#include "GrFontScaler.h"
#include "GrClipIterator.h"
@ -199,7 +199,7 @@ private:
static const GrContext::TextureKey gUNCACHED_KEY = ~0;
GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
GrContext::TextureKey key,
const GrSamplerState& sampler,
const GrSamplerState* sampler,
const SkBitmap& bitmap);

View File

@ -52,6 +52,9 @@ protected:
// override from SkPixelRef
virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset);
// override from SkPixelRef
virtual SkPixelRef* deepCopy(SkBitmap::Config dstConfig) SK_OVERRIDE;
private:
GrTexture* fTexture;
typedef SkROLockPixelsPixelRef INHERITED;
@ -72,6 +75,9 @@ protected:
// override from SkPixelRef
virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset);
// override from SkPixelRef
virtual SkPixelRef* deepCopy(SkBitmap::Config dstConfig) SK_OVERRIDE;
private:
GrRenderTarget* fRenderTarget;
typedef SkROLockPixelsPixelRef INHERITED;

View File

@ -12,6 +12,10 @@
#if defined(SK_BUILD_FOR_MAC)
#include <AGL/agl.h>
#elif defined(SK_BUILD_FOR_ANDROID)
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#elif defined(SK_BUILD_FOR_UNIX)
#include <X11/Xlib.h>
#include <GL/glx.h>
@ -43,6 +47,10 @@ public:
#elif defined(SK_BUILD_FOR_WIN32)
HDC fOldHDC;
HGLRC fOldHGLRC;
#elif defined(SK_BUILD_FOR_ANDROID)
EGLContext fOldEGLContext;
EGLDisplay fOldDisplay;
EGLSurface fOldSurface;
#endif
};
@ -63,6 +71,10 @@ private:
HDC fDeviceContext;
HGLRC fGlRenderContext;
static ATOM gWC;
#elif defined(SK_BUILD_FOR_ANDROID)
EGLContext fContext;
EGLDisplay fDisplay;
EGLSurface fSurface;
#endif
};

View File

@ -57,6 +57,8 @@ public:
virtual void flatten(SkFlattenableWriteBuffer&) const;
static SkPixelRef* Create(SkFlattenableReadBuffer& buffer);
SK_DECLARE_PIXEL_REF_REGISTRAR()
protected:
virtual void* onLockPixels(SkColorTable**);
virtual void onUnlockPixels();

View File

@ -24,6 +24,8 @@ public:
}
static SkPixelRef* Create(SkFlattenableReadBuffer&);
SK_DECLARE_PIXEL_REF_REGISTRAR()
// API to control the global pool
/** Return the amount specified as the budget for the cache (in bytes).

View File

@ -62,47 +62,43 @@ public:
const SkMatrix& initialTransform);
SK_API virtual ~SkPDFDevice();
virtual uint32_t getDeviceCapabilities() { return kVector_Capability; }
virtual uint32_t getDeviceCapabilities() SK_OVERRIDE;
virtual void clear(SkColor color);
virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
return false;
}
virtual void clear(SkColor color) SK_OVERRIDE;
/** These are called inside the per-device-layer loop for each draw call.
When these are called, we have already applied any saveLayer operations,
and are handling any looping from the paint, and any effects from the
DrawFilter.
*/
virtual void drawPaint(const SkDraw&, const SkPaint& paint);
virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
size_t count, const SkPoint[],
const SkPaint& paint);
const SkPaint& paint) SK_OVERRIDE;
virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint);
virtual void drawPath(const SkDraw&, const SkPath& origpath,
const SkPaint& paint, const SkMatrix* prePathMatrix,
bool pathIsMutable);
bool pathIsMutable) SK_OVERRIDE;
virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
const SkIRect* srcRectOrNull,
const SkMatrix& matrix, const SkPaint& paint);
const SkMatrix& matrix, const SkPaint&) SK_OVERRIDE;
virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
const SkPaint& paint);
const SkPaint& paint) SK_OVERRIDE;
virtual void drawText(const SkDraw&, const void* text, size_t len,
SkScalar x, SkScalar y, const SkPaint& paint);
SkScalar x, SkScalar y, const SkPaint&) SK_OVERRIDE;
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], SkScalar constY,
int scalarsPerPos, const SkPaint& paint);
int scalarsPerPos, const SkPaint&) SK_OVERRIDE;
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
const SkPaint& paint) SK_OVERRIDE;
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);
int indexCount, const SkPaint& paint) SK_OVERRIDE;
virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
const SkPaint&);
const SkPaint&) SK_OVERRIDE;
enum DrawingArea {
kContent_DrawingArea, // Drawing area for the page content.
@ -161,6 +157,10 @@ public:
return *(fFontGlyphUsage.get());
}
protected:
virtual bool onReadPixels(const SkBitmap& bitmap, int x, int y,
SkCanvas::Config8888) SK_OVERRIDE;
private:
// TODO(vandebo): push most of SkPDFDevice's state into a core object in
// order to get the right access levels without using friend.
@ -199,7 +199,7 @@ private:
virtual SkDevice* onCreateCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque,
Usage usage);
Usage usage) SK_OVERRIDE;
void init();
void cleanUp(bool clearFontUsage);

View File

@ -150,7 +150,7 @@ public:
void rotateY(SkScalar deg);
void rotateZ(SkScalar deg);
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
#endif

View File

@ -58,9 +58,9 @@ public:
int getNestLevel() const { return fNestLevel; }
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE;
virtual int save(SaveFlags) SK_OVERRIDE;
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE;
SaveFlags) SK_OVERRIDE;
virtual void restore() SK_OVERRIDE;
virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE;
@ -73,7 +73,7 @@ public:
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,
SkRegion::Op op = SkRegion::kIntersect_Op) SK_OVERRIDE;
SkRegion::Op) SK_OVERRIDE;
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
@ -81,13 +81,13 @@ public:
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 = NULL) SK_OVERRIDE;
const SkPaint* paint) SK_OVERRIDE;
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
const SkRect& dst, const SkPaint* paint = NULL) SK_OVERRIDE;
const SkRect& dst, const SkPaint* paint) SK_OVERRIDE;
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
const SkPaint* paint = NULL) SK_OVERRIDE;
const SkPaint* paint) SK_OVERRIDE;
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint = NULL) SK_OVERRIDE;
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,

View File

@ -0,0 +1,285 @@
/*
* 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 SkJSON_DEFINED
#define SkJSON_DEFINED
#include "SkTypes.h"
class SkStream;
class SkString;
class SkJSON {
public:
enum Type {
kObject,
kArray,
kString,
kInt,
kFloat,
kBool,
};
class Array;
class Object {
private:
struct Slot;
public:
Object();
Object(const Object&);
~Object();
/**
* Create a new slot with the specified name and value. The name
* parameter is copied, but ownership of the Object parameter is
* transferred. The Object parameter may be null, but the name must
* not be null.
*/
void addObject(const char name[], Object* value);
/**
* Create a new slot with the specified name and value. The name
* parameter is copied, but ownership of the Array parameter is
* transferred. The Array parameter may be null, but the name must
* not be null.
*/
void addArray(const char name[], Array* value);
/**
* Create a new slot with the specified name and value. Both parameters
* are copied. The value parameter may be null, but the name must
* not be null.
*/
void addString(const char name[], const char value[]);
/**
* Create a new slot with the specified name and value. The name
* parameter is copied, and must not be null.
*/
void addInt(const char name[], int32_t value);
/**
* Create a new slot with the specified name and value. The name
* parameter is copied, and must not be null.
*/
void addFloat(const char name[], float value);
/**
* Create a new slot with the specified name and value. The name
* parameter is copied, and must not be null.
*/
void addBool(const char name[], bool value);
/**
* Return the number of slots/fields in this object. These can be
* iterated using Iter.
*/
int count() const;
/**
* Returns true if a slot matching the name and Type is found.
*/
bool find(const char name[], Type) const;
bool findObject(const char name[], Object** = NULL) const;
bool findArray(const char name[], Array** = NULL) const;
bool findString(const char name[], SkString* = NULL) const;
bool findInt(const char name[], int32_t* = NULL) const;
bool findFloat(const char name[], float* = NULL) const;
bool findBool(const char name[], bool* = NULL) const;
/**
* Finds the first slot matching the name and Type and removes it.
* Returns true if found, false if not.
*/
bool remove(const char name[], Type);
void toDebugf() const;
/**
* Iterator class which returns all of the fields/slots in an Object,
* in the order that they were added.
*/
class Iter {
public:
Iter(const Object&);
/**
* Returns true when there are no more entries in the iterator.
* In this case, no other methods should be called.
*/
bool done() const;
/**
* Moves the iterator to the next element. Should only be called
* if done() returns false.
*/
void next();
/**
* Returns the type of the current element. Should only be called
* if done() returns false.
*/
Type type() const;
/**
* Returns the name of the current element. Should only be called
* if done() returns false.
*/
const char* name() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kObject.
*/
Object* objectValue() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kArray.
*/
Array* arrayValue() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kString.
*/
const char* stringValue() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kInt.
*/
int32_t intValue() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kFloat.
*/
float floatValue() const;
/**
* Returns the type of the current element. Should only be called
* if done() returns false and type() returns kBool.
*/
bool boolValue() const;
private:
Slot* fSlot;
};
private:
Slot* fHead;
Slot* fTail;
const Slot* findSlot(const char name[], Type) const;
Slot* addSlot(Slot*);
void dumpLevel(int level) const;
friend class Array;
};
class Array {
public:
/**
* Creates an array with the specified Type and element count. All
* entries are initialized to NULL/0/false.
*/
Array(Type, int count);
/**
* Creates an array of ints, initialized by copying the specified
* values.
*/
Array(const int32_t values[], int count);
/**
* Creates an array of floats, initialized by copying the specified
* values.
*/
Array(const float values[], int count);
/**
* Creates an array of bools, initialized by copying the specified
* values.
*/
Array(const bool values[], int count);
Array(const Array&);
~Array();
int count() const { return fCount; }
Type type() const { return fType; }
/**
* Replace the element at the specified index with the specified
* Object (which may be null). Ownership of the Object is transferred.
* Should only be called if the Array's type is kObject.
*/
void setObject(int index, Object*);
/**
* Replace the element at the specified index with the specified
* Array (which may be null). Ownership of the Array is transferred.
* Should only be called if the Array's type is kArray.
*/
void setArray(int index, Array*);
/**
* Replace the element at the specified index with a copy of the
* specified string (which may be null). Should only be called if the
* Array's type is kString.
*/
void setString(int index, const char str[]);
Object* const* objects() const {
SkASSERT(kObject == fType);
return fArray.fObjects;
}
Array* const* arrays() const {
SkASSERT(kObject == fType);
return fArray.fArrays;
}
const char* const* strings() const {
SkASSERT(kString == fType);
return fArray.fStrings;
}
int32_t* ints() const {
SkASSERT(kInt == fType);
return fArray.fInts;
}
float* floats() const {
SkASSERT(kFloat == fType);
return fArray.fFloats;
}
bool* bools() const {
SkASSERT(kBool == fType);
return fArray.fBools;
}
private:
int fCount;
Type fType;
union {
void* fVoids;
Object** fObjects;
Array** fArrays;
char** fStrings;
int32_t* fInts;
float* fFloats;
bool* fBools;
} fArray;
void init(Type, int count, const void* src);
void dumpLevel(int level) const;
friend class Object;
};
};
#endif

View File

@ -46,6 +46,20 @@
static const SkMScalar SK_MScalarPI = 3.14159265f;
#endif
#ifdef SK_SCALAR_IS_FLOAT
#define SkMScalarToScalar SkMScalarToFloat
#define SkScalarToMScalar SkFloatToMScalar
#else
#if SK_MSCALAR_IS_DOUBLE
// we don't have fixed <-> double macros, use double<->scalar macros
#define SkMScalarToScalar SkDoubleToScalar
#define SkScalarToMScalar SkScalarToDouble
#else
#define SkMScalarToScalar SkFloatToFixed
#define SkScalarToMScalar SkFixedToFloat
#endif
#endif
static const SkMScalar SK_MScalar1 = 1;
///////////////////////////////////////////////////////////////////////////////

View File

@ -23,53 +23,53 @@ public:
///////////////////////////////////////////////////////////////////////////
// These are forwarded to the N canvases we're referencing
virtual int save(SaveFlags flags = kMatrixClip_SaveFlag);
virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
SaveFlags flags = kARGB_ClipLayer_SaveFlag);
virtual void restore();
virtual bool translate(SkScalar dx, SkScalar dy);
virtual bool scale(SkScalar sx, SkScalar sy);
virtual bool rotate(SkScalar degrees);
virtual bool skew(SkScalar sx, SkScalar sy);
virtual bool concat(const SkMatrix& matrix);
virtual void setMatrix(const SkMatrix& matrix);
virtual int save(SaveFlags) SK_OVERRIDE;
virtual int saveLayer(const SkRect* bounds, const SkPaint*,
SaveFlags) SK_OVERRIDE;
virtual void restore() 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&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE;
virtual bool clipRegion(const SkRegion& deviceRgn,
SkRegion::Op op = SkRegion::kIntersect_Op);
SkRegion::Op) SK_OVERRIDE;
virtual void drawPaint(const SkPaint& paint);
virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
const SkPaint& paint);
virtual void drawRect(const SkRect& rect, const SkPaint& paint);
virtual void drawPath(const SkPath& path, const SkPaint& paint);
const SkPaint&) SK_OVERRIDE;
virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
const SkPaint* paint = NULL);
const SkPaint*) SK_OVERRIDE;
virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
const SkRect& dst, const SkPaint* paint = NULL);
const SkRect& dst, const SkPaint*) SK_OVERRIDE;
virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m,
const SkPaint* paint = NULL);
const SkPaint*) SK_OVERRIDE;
virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
const SkPaint* paint = NULL);
const SkPaint*) SK_OVERRIDE;
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint);
SkScalar y, const SkPaint&) SK_OVERRIDE;
virtual void drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint);
const SkPoint pos[], const SkPaint&) SK_OVERRIDE;
virtual void drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint);
const SkPaint&) SK_OVERRIDE;
virtual void drawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
virtual void drawPicture(SkPicture&);
const SkPaint&) SK_OVERRIDE;
virtual void drawPicture(SkPicture&) 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);
const SkPaint&) SK_OVERRIDE;
virtual SkBounder* setBounder(SkBounder* bounder);
virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter);
virtual SkBounder* setBounder(SkBounder*) SK_OVERRIDE;
virtual SkDrawFilter* setDrawFilter(SkDrawFilter*) SK_OVERRIDE;
private:
SkTDArray<SkCanvas*> fList;

View File

@ -0,0 +1,90 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkRefCnt.h"
#ifndef SkWGL_DEFINED
#define SkWGL_DEFINED
/**
* Working with WGL extensions can be a pain. Among the reasons is that You must
* have a GL context to get the proc addresses, but you want to use the procs to
* create a context in the first place. So you have to create a dummy GL ctx to
* get the proc addresses.
*
* This file helps by providing SkCreateWGLInterface(). It returns a struct of
* function pointers that it initializes. It also has a helper function to query
* for WGL extensions. It handles the fact that wglGetExtensionsString is itself
* an extension.
*/
#if !defined(WIN32_LEAN_AND_MEAN)
#define WIN32_LEAN_AND_MEAN
#define SK_LOCAL_LEAN_AND_MEAN
#endif
#include <Windows.h>
#if defined(SK_LOCAL_LEAN_AND_MEAN)
#undef WIN32_LEAN_AND_MEAN
#undef SK_LOCAL_LEAN_AND_MEAN
#endif
#define SK_WGL_DRAW_TO_WINDOW 0x2001
#define SK_WGL_ACCELERATION 0x2003
#define SK_WGL_SUPPORT_OPENGL 0x2010
#define SK_WGL_DOUBLE_BUFFER 0x2011
#define SK_WGL_COLOR_BITS 0x2014
#define SK_WGL_ALPHA_BITS 0x201B
#define SK_WGL_STENCIL_BITS 0x2023
#define SK_WGL_FULL_ACCELERATION 0x2027
#define SK_WGL_SAMPLE_BUFFERS 0x2041
#define SK_WGL_SAMPLES 0x2042
#define SK_WGL_CONTEXT_MAJOR_VERSION 0x2091
#define SK_WGL_CONTEXT_MINOR_VERSION 0x2092
#define SK_WGL_CONTEXT_LAYER_PLANE 0x2093
#define SK_WGL_CONTEXT_FLAGS 0x2094
#define SK_WGL_CONTEXT_PROFILE_MASK 0x9126
#define SK_WGL_CONTEXT_DEBUG_BIT 0x0001
#define SK_WGL_CONTEXT_FORWARD_COMPATIBLE_BIT 0x0002
#define SK_WGL_CONTEXT_CORE_PROFILE_BIT 0x00000001
#define SK_WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#define SK_WGL_CONTEXT_ES2_PROFILE_BIT 0x00000004
#define SK_ERROR_INVALID_VERSION 0x2095
#define SK_ERROR_INVALID_PROFILE 0x2096
class SkWGLExtensions {
public:
SkWGLExtensions();
/**
* Determines if an extensions is available for a given DC.
* WGL_extensions_string is considered a prerequisite for all other
* extensions. It is necessary to check this before calling other class
* functions.
*/
bool hasExtension(HDC dc, const char* ext) const;
const char* getExtensionsString(HDC hdc) const;
BOOL choosePixelFormat(HDC hdc, const int*, const FLOAT*, UINT, int*, UINT*) const;
BOOL getPixelFormatAttribiv(HDC, int, int, UINT, const int*, int*) const;
BOOL getPixelFormatAttribfv(HDC hdc, int, int, UINT, const int*, FLOAT*) const;
HGLRC createContextAttribs(HDC, HGLRC, const int *) const;
private:
typedef const char* (WINAPI *GetExtensionsStringProc)(HDC hdc);
typedef BOOL (WINAPI *ChoosePixelFormatProc)(HDC hdc, const int *, const FLOAT *, UINT, int *, UINT *);
typedef BOOL (WINAPI *GetPixelFormatAttribivProc)(HDC, int, int, UINT, const int*, int*);
typedef BOOL (WINAPI *GetPixelFormatAttribfvProc)(HDC hdc, int, int, UINT, const int*, FLOAT*);
typedef HGLRC (WINAPI *CreateContextAttribsProc)(HDC hDC, HGLRC, const int *);
GetExtensionsStringProc fGetExtensionsString;
ChoosePixelFormatProc fChoosePixelFormat;
GetPixelFormatAttribfvProc fGetPixelFormatAttribfv;
GetPixelFormatAttribivProc fGetPixelFormatAttribiv;
CreateContextAttribsProc fCreateContextAttribs;
};
#endif

View File

@ -14,6 +14,7 @@
#include "SkRect.h"
#include "SkDOM.h"
#include "SkTDict.h"
#include "SkMatrix.h"
class SkCanvas;
class SkLayerView;
@ -80,6 +81,12 @@ public:
/** Return a rectangle set to [0, 0, width, height] */
void getLocalBounds(SkRect* bounds) const;
/** Loc - the view's offset with respect to its parent in its view hiearchy.
NOTE: For more complex transforms, use Local Matrix. The tranformations
are applied in the following order:
canvas->translate(fLoc.fX, fLoc.fY);
canvas->concat(fMatrix);
*/
/** Return the view's left edge */
SkScalar locX() const { return fLoc.fX; }
/** Return the view's top edge */
@ -89,6 +96,18 @@ public:
void setLoc(const SkPoint& loc) { this->setLoc(loc.fX, loc.fY); }
void setLocX(SkScalar x) { this->setLoc(x, fLoc.fY); }
void setLocY(SkScalar y) { this->setLoc(fLoc.fX, y); }
/** Local Matrix - matrix used to tranform the view with respect to its
parent in its view hiearchy. Use setLocalMatrix to apply matrix
transformations to the current view and in turn affect its children.
NOTE: For simple offsets, use Loc. The transformations are applied in
the following order:
canvas->translate(fLoc.fX, fLoc.fY);
canvas->concat(fMatrix);
*/
const SkMatrix& getLocalMatrix() const { return fMatrix; }
void setLocalMatrix(const SkMatrix& matrix);
/** Offset (move) the view by the specified dx and dy. This does not affect the view's size */
void offset(SkScalar dx, SkScalar dy);
@ -338,6 +357,7 @@ protected:
private:
SkScalar fWidth, fHeight;
SkMatrix fMatrix;
SkPoint fLoc;
SkView* fParent;
SkView* fFirstChild;
@ -354,6 +374,8 @@ private:
bool setFocusView(SkView* fvOrNull);
SkView* acceptFocus(FocusDirection);
void detachFromParent_NoLayout();
/** Compute the matrix to transform view-local coordinates into global ones */
void localToGlobal(SkMatrix* matrix) const;
};
#endif

View File

@ -108,7 +108,7 @@ private:
#include "SkOSWindow_Mac.h"
#elif defined(SK_BUILD_FOR_WIN)
#include "SkOSWindow_Win.h"
#elif defined(ANDROID)
#elif defined(SK_BUILD_FOR_ANDROID)
#include "SkOSWindow_Android.h"
#elif defined(SK_BUILD_FOR_UNIX)
#include "SkOSWindow_Unix.h"

View File

@ -255,7 +255,7 @@ bool SkDisplayEvent::setProperty(int index, SkScriptValue& value) {
return true;
}
#ifdef ANDROID
#ifdef SK_BUILD_FOR_ANDROID
#include "SkMetaData.h"
#include "SkParse.h"

View File

@ -209,7 +209,7 @@ void SkAAClip::validate() const {
prevOffset = yoff->fOffset;
const uint8_t* row = head->data() + yoff->fOffset;
size_t rowLength = compute_row_length(row, fBounds.width());
SkASSERT(yoff->fOffset + rowLength <= head->fDataSize);
SkASSERT(yoff->fOffset + rowLength <= (size_t) head->fDataSize);
yoff += 1;
}
// check the last entry;
@ -460,6 +460,8 @@ bool SkAAClip::trimTopBottom() {
return false;
}
this->validate();
const int width = fBounds.width();
RunHead* head = fRunHead;
YOffset* yoff = head->yoffsets();
@ -498,6 +500,10 @@ bool SkAAClip::trimTopBottom() {
SkASSERT(!fBounds.isEmpty());
head->fRowCount -= skip;
SkASSERT(head->fRowCount > 0);
this->validate();
// need to reset this after the memmove
base = head->data();
}
// Look to trim away empty rows from the bottom.
@ -520,6 +526,7 @@ bool SkAAClip::trimTopBottom() {
head->fRowCount -= skip;
SkASSERT(head->fRowCount > 0);
}
this->validate();
return true;
}
@ -675,6 +682,20 @@ bool SkAAClip::setRect(const SkRect& r, bool doAA) {
return this->setPath(path, NULL, doAA);
}
static void append_run(SkTDArray<uint8_t>& array, uint8_t value, int count) {
SkASSERT(count >= 0);
while (count > 0) {
int n = count;
if (n > 255) {
n = 255;
}
uint8_t* data = array.append(2);
data[0] = n;
data[1] = value;
count -= n;
}
}
bool SkAAClip::setRegion(const SkRegion& rgn) {
if (rgn.isEmpty()) {
return this->setEmpty();
@ -683,6 +704,7 @@ bool SkAAClip::setRegion(const SkRegion& rgn) {
return this->setRect(rgn.getBounds());
}
#if 0
SkAAClip clip;
SkRegion::Iterator iter(rgn);
for (; !iter.done(); iter.next()) {
@ -690,6 +712,71 @@ bool SkAAClip::setRegion(const SkRegion& rgn) {
}
this->swap(clip);
return !this->isEmpty();
#else
const SkIRect& bounds = rgn.getBounds();
const int offsetX = bounds.fLeft;
const int offsetY = bounds.fTop;
SkTDArray<YOffset> yArray;
SkTDArray<uint8_t> xArray;
yArray.setReserve(SkMin32(bounds.height(), 1024));
xArray.setReserve(SkMin32(bounds.width() * 128, 64 * 1024));
SkRegion::Iterator iter(rgn);
int prevRight = 0;
int prevBot = 0;
YOffset* currY = NULL;
for (; !iter.done(); iter.next()) {
const SkIRect& r = iter.rect();
SkASSERT(bounds.contains(r));
int bot = r.fBottom - offsetY;
SkASSERT(bot >= prevBot);
if (bot > prevBot) {
if (currY) {
// flush current row
append_run(xArray, 0, bounds.width() - prevRight);
}
// did we introduce an empty-gap from the prev row?
int top = r.fTop - offsetY;
if (top > prevBot) {
currY = yArray.append();
currY->fY = top - 1;
currY->fOffset = xArray.count();
append_run(xArray, 0, bounds.width());
}
// create a new record for this Y value
currY = yArray.append();
currY->fY = bot - 1;
currY->fOffset = xArray.count();
prevRight = 0;
prevBot = bot;
}
int x = r.fLeft - offsetX;
append_run(xArray, 0, x - prevRight);
int w = r.fRight - r.fLeft;
append_run(xArray, 0xFF, w);
prevRight = x + w;
SkASSERT(prevRight <= bounds.width());
}
// flush last row
append_run(xArray, 0, bounds.width() - prevRight);
// now pack everything into a RunHead
RunHead* head = RunHead::Alloc(yArray.count(), xArray.bytes());
memcpy(head->yoffsets(), yArray.begin(), yArray.bytes());
memcpy(head->data(), xArray.begin(), xArray.bytes());
this->setEmpty();
fBounds = bounds;
fRunHead = head;
this->validate();
return true;
#endif
}
///////////////////////////////////////////////////////////////////////////////
@ -839,6 +926,62 @@ public:
SkASSERT(row->fWidth <= fBounds.width());
}
void addColumn(int x, int y, U8CPU alpha, int height) {
SkASSERT(fBounds.contains(x, y + height - 1));
this->addRun(x, y, alpha, 1);
this->flushRowH(fCurrRow);
y -= fBounds.fTop;
SkASSERT(y == fCurrRow->fY);
fCurrRow->fY = y + height - 1;
}
void addRectRun(int x, int y, int width, int height) {
SkASSERT(fBounds.contains(x + width - 1, y + height - 1));
this->addRun(x, y, 0xFF, width);
// we assum the rect must be all we'll see for these scanlines
// so we ensure our row goes all the way to our right
this->flushRowH(fCurrRow);
y -= fBounds.fTop;
SkASSERT(y == fCurrRow->fY);
fCurrRow->fY = y + height - 1;
}
void addAntiRectRun(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) {
SkASSERT(fBounds.contains(x + width - 1 +
(leftAlpha > 0 ? 1 : 0) + (rightAlpha > 0 ? 1 : 0),
y + height - 1));
SkASSERT(width >= 0);
// Conceptually we're always adding 3 runs, but we should
// merge or omit them if possible.
if (leftAlpha == 0xFF) {
width++;
} else if (leftAlpha > 0) {
this->addRun(x++, y, leftAlpha, 1);
}
if (rightAlpha == 0xFF) {
width++;
}
if (width > 0) {
this->addRun(x, y, 0xFF, width);
}
if (rightAlpha > 0 && rightAlpha < 255) {
this->addRun(x + width, y, rightAlpha, 1);
}
// we assume the rect must be all we'll see for these scanlines
// so we ensure our row goes all the way to our right
this->flushRowH(fCurrRow);
y -= fBounds.fTop;
SkASSERT(y == fCurrRow->fY);
fCurrRow->fY = y + height - 1;
}
bool finish(SkAAClip* target) {
this->flushRow(false);
@ -878,7 +1021,7 @@ public:
size_t n = row->fData->count();
memcpy(data, row->fData->begin(), n);
#ifdef SK_DEBUG
int bytesNeeded = compute_row_length(data, fBounds.width());
size_t bytesNeeded = compute_row_length(data, fBounds.width());
SkASSERT(bytesNeeded == n);
#endif
data += n;
@ -922,7 +1065,9 @@ public:
SkASSERT(!(count & 1));
int w = 0;
for (int x = 0; x < count; x += 2) {
w += ptr[0];
int n = ptr[0];
SkASSERT(n > 0);
w += n;
SkASSERT(w <= fWidth);
ptr += 2;
}
@ -938,17 +1083,19 @@ public:
}
private:
void flushRowH(Row* row) {
// flush current row if needed
if (row->fWidth < fWidth) {
AppendRun(*row->fData, 0, fWidth - row->fWidth);
row->fWidth = fWidth;
}
}
Row* flushRow(bool readyForAnother) {
Row* next = NULL;
int count = fRows.count();
if (count > 0) {
// flush current row if needed
Row* curr = &fRows[count - 1];
if (curr->fWidth < fWidth) {
AppendRun(*curr->fData, 0, fWidth - curr->fWidth);
curr->fWidth = fWidth;
}
this->flushRowH(&fRows[count - 1]);
}
if (count > 1) {
// are our last two runs the same?
@ -1009,11 +1156,28 @@ public:
}
}
virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE
{ unexpected(); }
/**
Must evaluate clips in scan-line order, so don't want to allow blitV(),
but an AAClip can be clipped down to a single pixel wide, so we
must support it (given AntiRect semantics: minimum width is 2).
Instead we'll rely on the runtime asserts to guarantee Y monotonicity;
any failure cases that misses may have minor artifacts.
*/
virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE {
this->recordMinY(y);
fBuilder->addColumn(x, y, alpha, height);
}
// let the default impl call blitH
// virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE
virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE {
this->recordMinY(y);
fBuilder->addRectRun(x, y, width, height);
}
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE {
this->recordMinY(y);
fBuilder->addAntiRectRun(x, y, width, height, leftAlpha, rightAlpha);
}
virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE
{ unexpected(); }
@ -1171,7 +1335,7 @@ static AlphaProc find_alpha_proc(SkRegion::Op op) {
case SkRegion::kXOR_Op:
return xorAlphaProc;
default:
SkASSERT(!"unexpected region op");
SkDEBUGFAIL("unexpected region op");
return sectAlphaProc;
}
}
@ -1444,7 +1608,7 @@ bool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig,
break;
default:
SkASSERT(!"unknown region op");
SkDEBUGFAIL("unknown region op");
return !this->isEmpty();
}
@ -1561,6 +1725,7 @@ static void expand_row_to_mask(uint8_t* SK_RESTRICT mask,
row += 2;
width -= n;
}
SkASSERT(0 == width);
}
void SkAAClip::copyToMask(SkMask* mask) const {
@ -1831,7 +1996,7 @@ template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN,
static MergeAAProc find_merge_aa_proc(SkMask::Format format) {
switch (format) {
case SkMask::kBW_Format:
SkASSERT(!"unsupported");
SkDEBUGFAIL("unsupported");
return NULL;
case SkMask::kA8_Format:
case SkMask::k3D_Format: {
@ -1847,7 +2012,7 @@ static MergeAAProc find_merge_aa_proc(SkMask::Format format) {
return (MergeAAProc)proc32;
}
default:
SkASSERT(!"unsupported");
SkDEBUGFAIL("unsupported");
return NULL;
}
}

View File

@ -10,7 +10,7 @@
#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypes.h"
#ifdef SK_BUILD_FOR_UNIX
#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
@ -27,6 +27,35 @@
namespace skia_advanced_typeface_metrics_utils {
const int16_t kInvalidAdvance = SK_MinS16;
const int16_t kDontCareAdvance = SK_MinS16 + 1;
template <typename Data>
void stripUninterestingTrailingAdvancesFromRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
SkASSERT(false);
}
template <>
void stripUninterestingTrailingAdvancesFromRange<int16_t>(
SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
SkASSERT(range);
int expectedAdvanceCount = range->fEndId - range->fStartId + 1;
if (range->fAdvance.count() < expectedAdvanceCount) {
return;
}
for (int i = expectedAdvanceCount - 1; i >= 0; --i) {
if (range->fAdvance[i] != kDontCareAdvance &&
range->fAdvance[i] != kInvalidAdvance &&
range->fAdvance[i] != 0) {
range->fEndId = range->fStartId + i;
break;
}
}
}
template <typename Data>
void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
int startId) {
@ -43,6 +72,29 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
return nextSlot->get();
}
template <typename Data>
void zeroWildcardsInRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range) {
SkASSERT(false);
}
template <>
void zeroWildcardsInRange<int16_t>(
SkAdvancedTypefaceMetrics::AdvanceMetric<int16_t>* range) {
SkASSERT(range);
if (range->fType != SkAdvancedTypefaceMetrics::WidthRange::kRange) {
return;
}
SkASSERT(range->fAdvance.count() == range->fEndId - range->fStartId + 1);
// Zero out wildcards.
for (int i = 0; i < range->fAdvance.count(); ++i) {
if (range->fAdvance[i] == kDontCareAdvance) {
range->fAdvance[i] = 0;
}
}
}
template <typename Data>
void finishRange(
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
@ -51,14 +103,20 @@ void finishRange(
type) {
range->fEndId = endId;
range->fType = type;
stripUninterestingTrailingAdvancesFromRange(range);
int newLength;
if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
newLength = endId - range->fStartId + 1;
newLength = range->fEndId - range->fStartId + 1;
} else {
if (range->fEndId == range->fStartId) {
range->fType =
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange;
}
newLength = 1;
}
SkASSERT(range->fAdvance.count() >= newLength);
range->fAdvance.setCount(newLength);
zeroWildcardsInRange(range);
}
template <typename Data, typename FontHandle>
@ -68,75 +126,124 @@ SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
// Assuming that an ASCII representation of a width or a glyph id is,
// on average, 3 characters long gives the following cut offs for
// using different range types:
// When currently in a range
// - Removing 4 0's is a win
// - Removing 5 repeats is a win
// When not currently in a range
// - Removing 1 0 is a win
// - Removing 3 repeats is a win
// Assuming that on average, the ASCII representation of an advance plus
// a space is 8 characters and the ASCII representation of a glyph id is 3
// characters, then the following cut offs for using different range types
// apply:
// The cost of stopping and starting the range is 7 characers
// a. Removing 4 0's or don't care's is a win
// The cost of stopping and starting the range plus a run is 22
// characters
// b. Removing 3 repeating advances is a win
// c. Removing 2 repeating advances and 3 don't cares is a win
// When not currently in a range the cost of a run over a range is 16
// characaters, so:
// d. Removing a leading 0/don't cares is a win because it is omitted
// e. Removing 2 repeating advances is a win
SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* prevRange = NULL;
curRange = appendRange(&result, 0);
Data lastAdvance = SK_MinS16;
int repeats = 0;
Data lastAdvance = kInvalidAdvance;
int repeatedAdvances = 0;
int wildCardsInRun = 0;
int leadingWildCards = 0;
int trailingWildCards = 0;
uint32_t subsetIndex = 0;
for (int gId = 0; gId <= num_glyphs; gId++) {
Data advance = 0;
if (gId < num_glyphs) {
// Limit the loop count to glyph id ranges provided.
int firstIndex = 0;
int lastIndex = num_glyphs;
if (subsetGlyphIDs) {
firstIndex = static_cast<int>(subsetGlyphIDs[0]);
lastIndex =
static_cast<int>(subsetGlyphIDs[subsetGlyphIDsLength - 1]) + 1;
}
curRange = appendRange(&result, firstIndex);
for (int gId = firstIndex; gId <= lastIndex; gId++) {
Data advance = kInvalidAdvance;
if (gId < lastIndex) {
// Get glyph id only when subset is NULL, or the id is in subset.
if (!subsetGlyphIDs ||
(subsetIndex < subsetGlyphIDsLength &&
static_cast<uint32_t>(gId) == subsetGlyphIDs[subsetIndex])) {
SkAssertResult(getAdvance(fontHandle, gId, &advance));
++subsetIndex;
}
} else {
advance = SK_MinS16;
advance = kDontCareAdvance;
}
}
if (advance == lastAdvance) {
repeats++;
} else if (curRange->fAdvance.count() == repeats + 1) {
if (lastAdvance == 0 && repeats >= 0) {
repeatedAdvances++;
trailingWildCards = 0;
} else if (advance == kDontCareAdvance) {
wildCardsInRun++;
trailingWildCards++;
} else if (curRange->fAdvance.count() ==
repeatedAdvances + 1 + wildCardsInRun) { // All in run.
if (lastAdvance == 0) {
resetRange(curRange, gId);
} else if (repeats >= 2) {
trailingWildCards = 0;
} else if (repeatedAdvances + 1 >= 2 || trailingWildCards >= 4) {
finishRange(curRange, gId - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRun);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
trailingWildCards = 0;
}
repeats = 0;
repeatedAdvances = 0;
wildCardsInRun = trailingWildCards;
leadingWildCards = trailingWildCards;
trailingWildCards = 0;
} else {
if (lastAdvance == 0 && repeats >= 3) {
finishRange(curRange, gId - repeats - 2,
if (lastAdvance == 0 &&
repeatedAdvances + 1 + wildCardsInRun >= 4) {
finishRange(curRange,
gId - repeatedAdvances - wildCardsInRun - 2,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
} else if (repeats >= 4) {
finishRange(curRange, gId - repeats - 2,
trailingWildCards = 0;
} else if (trailingWildCards >= 4 && repeatedAdvances + 1 < 2) {
finishRange(curRange,
gId - trailingWildCards - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
curRange = appendRange(&curRange->fNext, gId - repeats - 1);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
trailingWildCards = 0;
} else if (lastAdvance != 0 &&
(repeatedAdvances + 1 >= 3 ||
(repeatedAdvances + 1 >= 2 && wildCardsInRun >= 3))) {
finishRange(curRange,
gId - repeatedAdvances - wildCardsInRun - 2,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
curRange =
appendRange(&curRange->fNext,
gId - repeatedAdvances - wildCardsInRun - 1);
curRange->fAdvance.append(1, &lastAdvance);
finishRange(curRange, gId - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRun);
prevRange = curRange;
curRange = appendRange(&curRange->fNext, gId);
trailingWildCards = 0;
}
repeats = 0;
repeatedAdvances = 0;
wildCardsInRun = trailingWildCards;
leadingWildCards = trailingWildCards;
trailingWildCards = 0;
}
curRange->fAdvance.append(1, &advance);
if (advance != kDontCareAdvance) {
lastAdvance = advance;
}
if (curRange->fStartId == num_glyphs) {
}
if (curRange->fStartId == lastIndex) {
SkASSERT(prevRange);
SkASSERT(prevRange->fNext->fStartId == num_glyphs);
SkASSERT(prevRange->fNext->fStartId == lastIndex);
prevRange->fNext.reset();
} else {
finishRange(curRange, num_glyphs - 1,
finishRange(curRange, lastIndex - 1,
SkAdvancedTypefaceMetrics::WidthRange::kRange);
}
return result.release();
@ -151,7 +258,7 @@ template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
const uint32_t* subsetGlyphIDs,
uint32_t subsetGlyphIDsLength,
bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
#elif defined(SK_BUILD_FOR_UNIX)
#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID)
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
FT_Face face,
int num_glyphs,

View File

@ -12,19 +12,35 @@
#include "SkBlitter.h"
/** Sparse array of run-length-encoded alpha (supersampling coverage) values.
Sparseness allows us to independently compose several paths into the
same SkAlphaRuns buffer.
*/
class SkAlphaRuns {
public:
int16_t* fRuns;
uint8_t* fAlpha;
/// Returns true if the scanline contains only a single run,
/// of alpha value 0.
bool empty() const {
SkASSERT(fRuns[0] > 0);
return fAlpha[0] == 0 && fRuns[fRuns[0]] == 0;
}
/// Reinitialize for a new scanline.
void reset(int width);
/**
* Insert into the buffer a run starting at (x-offsetX):
* if startAlpha > 0
* one pixel with value += startAlpha,
* max 255
* if middleCount > 0
* middleCount pixels with value += maxValue
* if stopAlpha > 0
* one pixel with value += stopAlpha
* Returns the offsetX value that should be passed on the next call,
* assuming we're on the same scanline. If the caller is switching
* scanlines, then offsetX should be 0 when this is called.
@ -35,8 +51,22 @@ public:
SkDEBUGCODE(void assertValid(int y, int maxStep) const;)
SkDEBUGCODE(void dump() const;)
/**
* Break the runs in the buffer at offsets x and x+count, properly
* updating the runs to the right and left.
* i.e. from the state AAAABBBB, run-length encoded as A4B4,
* Break(..., 2, 5) would produce AAAABBBB rle as A2A2B3B1.
* Allows add() to sum another run to some of the new sub-runs.
* i.e. adding ..CCCCC. would produce AADDEEEB, rle as A2D2E3B1.
*/
static void Break(int16_t runs[], uint8_t alpha[], int x, int count);
/**
* Cut (at offset x in the buffer) a run into two shorter runs with
* matching alpha values.
* Used by the RectClipBlitter to trim a RLE encoding to match the
* clipping rectangle.
*/
static void BreakAt(int16_t runs[], uint8_t alpha[], int x) {
while (x > 0) {
int n = runs[0];

View File

@ -173,7 +173,7 @@ int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) {
bpp = 4;
break;
default:
SkASSERT(!"unknown config");
SkDEBUGFAIL("unknown config");
bpp = 0; // error
break;
}
@ -211,7 +211,7 @@ int SkBitmap::ComputeRowBytes(Config c, int width) {
rowBytes.shiftLeft(2);
break;
default:
SkASSERT(!"unknown config");
SkDEBUGFAIL("unknown config");
break;
}
return isPos32Bits(rowBytes) ? rowBytes.get32() : 0;
@ -409,6 +409,7 @@ uint32_t SkBitmap::getGenerationID() const {
}
void SkBitmap::notifyPixelsChanged() const {
SkASSERT(!this->isImmutable());
if (fPixelRef) {
fPixelRef->notifyPixelsChanged();
} else {
@ -456,8 +457,8 @@ Sk64 SkBitmap::getSafeSize64() const {
return ComputeSafeSize64(getConfig(), fWidth, fHeight, fRowBytes);
}
bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes)
const {
bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize,
int dstRowBytes, bool preserveDstPad) const {
if (dstRowBytes == -1)
dstRowBytes = fRowBytes;
@ -468,7 +469,7 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes)
dst == NULL || (getPixels() == NULL && pixelRef() == NULL))
return false;
if (static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) {
size_t safeSize = getSafeSize();
if (safeSize > dstSize || safeSize == 0)
return false;
@ -502,43 +503,21 @@ bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, int dstRowBytes)
}
}
bool SkBitmap::copyPixelsFrom(const void* const src, size_t srcSize,
int srcRowBytes) {
if (srcRowBytes == -1)
srcRowBytes = fRowBytes;
SkASSERT(srcRowBytes >= 0);
size_t safeSize = getSafeSize();
uint32_t rowBytes = ComputeRowBytes(getConfig(), fWidth);
if (getConfig() == kRLE_Index8_Config || src == NULL ||
static_cast<uint32_t>(srcRowBytes) < rowBytes ||
safeSize == 0 ||
srcSize < ComputeSafeSize(getConfig(), fWidth, fHeight, srcRowBytes)) {
return false;
}
SkAutoLockPixels lock(*this);
if (static_cast<uint32_t>(srcRowBytes) == fRowBytes) {
// This implementation will write bytes beyond the end of each row,
// excluding the last row, if the bitmap's stride is greater than
// strictly required by the current config.
memcpy(getPixels(), src, safeSize);
} else {
// Just copy the bytes we need on each line.
const uint8_t* srcP = reinterpret_cast<const uint8_t*>(src);
uint8_t* dstP = reinterpret_cast<uint8_t*>(getPixels());
for (uint32_t row = 0; row < fHeight;
row++, srcP += srcRowBytes, dstP += fRowBytes) {
memcpy(dstP, srcP, rowBytes);
}
}
return true;
}
///////////////////////////////////////////////////////////////////////////////
bool SkBitmap::isImmutable() const {
return fPixelRef ? fPixelRef->isImmutable() :
fFlags & kImageIsImmutable_Flag;
}
void SkBitmap::setImmutable() {
if (fPixelRef) {
fPixelRef->setImmutable();
} else {
fFlags |= kImageIsImmutable_Flag;
}
}
bool SkBitmap::isOpaque() const {
switch (fConfig) {
case kNo_Config:
@ -568,7 +547,7 @@ bool SkBitmap::isOpaque() const {
return true;
default:
SkASSERT(!"unknown bitmap config pased to isOpaque");
SkDEBUGFAIL("unknown bitmap config pased to isOpaque");
return false;
}
}
@ -619,11 +598,11 @@ void* SkBitmap::getAddr(int x, int y) const {
base += x >> 3;
break;
case kRLE_Index8_Config:
SkASSERT(!"Can't return addr for kRLE_Index8_Config");
SkDEBUGFAIL("Can't return addr for kRLE_Index8_Config");
base = NULL;
break;
default:
SkASSERT(!"Can't return addr for config");
SkDEBUGFAIL("Can't return addr for config");
base = NULL;
break;
}
@ -973,6 +952,29 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
return true;
}
bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const {
if (!this->canCopyTo(dstConfig)) {
return false;
}
// If we have a PixelRef, and it supports deep copy, use it.
// Currently supported only by texture-backed bitmaps.
if (fPixelRef) {
SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig);
if (pixelRef) {
dst->setConfig(dstConfig, fWidth, fHeight);
dst->setPixelRef(pixelRef)->unref();
return true;
}
}
if (this->getTexture()) {
return false;
} else {
return this->copyTo(dst, dstConfig, NULL);
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@ -1499,7 +1501,7 @@ void SkBitmap::unflatten(SkFlattenableReadBuffer& buffer) {
case SERIALIZE_PIXELTYPE_NONE:
break;
default:
SkASSERT(!"unrecognized pixeltype in serialized data");
SkDEBUGFAIL("unrecognized pixeltype in serialized data");
sk_throw();
}
}

View File

@ -81,6 +81,10 @@ static bool only_scale_and_translate(const SkMatrix& matrix) {
return (matrix.getType() & ~mask) == 0;
}
bool SkBitmapProcShader::isOpaque() const {
return fRawBitmap.isOpaque();
}
bool SkBitmapProcShader::setContext(const SkBitmap& device,
const SkPaint& paint,
const SkMatrix& matrix) {
@ -285,8 +289,7 @@ SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
return shader;
}
static SkFlattenable::Registrar gBitmapProcShaderReg("SkBitmapProcShader",
SkBitmapProcShader::CreateProc);
SK_DEFINE_FLATTENABLE_REGISTRAR(SkBitmapProcShader)
///////////////////////////////////////////////////////////////////////////////

View File

@ -18,6 +18,7 @@ public:
SkBitmapProcShader(const SkBitmap& src, TileMode tx, TileMode ty);
// overrides from SkShader
virtual bool isOpaque() const SK_OVERRIDE;
virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&);
virtual uint32_t getFlags() { return fFlags; }
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count);
@ -36,6 +37,7 @@ public:
// override from flattenable
virtual bool toDumpString(SkString* str) const;
SK_DECLARE_FLATTENABLE_REGISTRAR()
protected:
SkBitmapProcShader(SkFlattenableReadBuffer& );
virtual void flatten(SkFlattenableWriteBuffer& );

View File

@ -7,12 +7,6 @@
*/
#ifdef __arm__
#ifdef ANDROID
#include <machine/cpu-features.h>
#endif
#endif
#include "SkColorPriv.h"
/*

View File

@ -19,7 +19,7 @@ static SkTileModeProc get_tilemode_proc(SkShader::TileMode mode)
case SkShader::kMirror_TileMode:
return do_mirror_mod;
default:
SkASSERT(!"unknown mode");
SkDEBUGFAIL("unknown mode");
return NULL;
}
}
@ -338,7 +338,7 @@ SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
else
return SkNEW_ARGS(ARGB32_Point_Mirror_Mod_Sampler, (bm));
default:
SkASSERT(!"unknown mode");
SkDEBUGFAIL("unknown mode");
}
}
else { // tmx != tmy
@ -365,7 +365,7 @@ SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
else
return SkNEW_ARGS(RGB16_Point_Mirror_Mod_Sampler, (bm));
default:
SkASSERT(!"unknown mode");
SkDEBUGFAIL("unknown mode");
}
}
else { // tmx != tmy
@ -392,7 +392,7 @@ SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
else
return SkNEW_ARGS(Index8_Point_Mirror_Mod_Sampler, (bm));
default:
SkASSERT(!"unknown mode");
SkDEBUGFAIL("unknown mode");
}
}
else { // tmx != tmy
@ -408,7 +408,7 @@ SkBitmapSampler* SkBitmapSampler::Create(const SkBitmap& bm, bool doFilter,
break;
default:
SkASSERT(!"unknown device");
SkDEBUGFAIL("unknown device");
}
return SkNEW_ARGS(SkNullBitmapSampler, (bm, doFilter, tmx, tmy));
}

Some files were not shown because too many files have changed in this diff Show More