[PATCH 08/15] Bug 1017113 - Update Skia to 2014-07-28 r=upstream

This commit is contained in:
George Wright 2014-07-28 15:06:12 -04:00
parent babadb79f6
commit b50d70f43c
900 changed files with 53274 additions and 33312 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1046533 needs a clobber on Android.
Skia update needs a CLOBBER on all platforms.

View File

@ -2,7 +2,7 @@ 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 r13827.
This is an import of Skia from 2014-07-28 (b1ab5fdd11bb358d738c1bfa63737dc65174a281)
To update to a new version of Skia:

View File

@ -188,19 +188,18 @@
*/
//#define SK_ATOMICS_PLATFORM_H "SkAtomics_xxx.h"
//#define SK_MUTEX_PLATFORM_H "SkMutex_xxx.h"
# if defined(_MSC_VER)
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_win.h"
# elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_android.h"
# else
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_sync.h"
# endif
#if defined(_MSC_VER)
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_win.h"
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_win.h"
#else
# define SK_ATOMICS_PLATFORM_H "skia/SkAtomics_sync.h"
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_pthread.h"
#endif
# if defined(SK_BUILD_FOR_WIN32)
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_win.h"
# else
# define SK_MUTEX_PLATFORM_H "skia/SkMutex_pthread.h"
# endif
#if defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
# define SK_BARRIERS_PLATFORM_H "skia/SkBarriers_arm.h"
#else
# define SK_BARRIERS_PLATFORM_H "skia/SkBarriers_x86.h"
#endif
#define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0
@ -209,3 +208,5 @@
#define SK_SUPPORT_LEGACY_GETTOPDEVICE
#define SK_SUPPORT_LEGACY_BITMAP_CONFIG
#define SK_IGNORE_ETC1_SUPPORT
#endif

View File

@ -35,15 +35,21 @@ public:
kCFF_Font,
kTrueType_Font,
kOther_Font,
kNotEmbeddable_Font
};
// The type of the underlying font program. This field determines which
// of the following fields are valid. If it is kOther_Font or
// kNotEmbeddable_Font, the per glyph information will never be populated.
// of the following fields are valid. If it is kOther_Font the per glyph
// information will never be populated.
FontType fType;
// fMultiMaster may be true for Type1_Font or CFF_Font.
bool fMultiMaster;
enum FontFlags {
kEmpty_FontFlag = 0x0, //!<No flags set
kMultiMaster_FontFlag = 0x1, //!<May be true for Type1 or CFF fonts.
kNotEmbeddable_FontFlag = 0x2, //!<May not be embedded.
kNotSubsettable_FontFlag = 0x4, //!<May not be subset.
};
// Global font flags.
FontFlags fFlags;
uint16_t fLastGlyphID; // The last valid glyph ID in the font.
uint16_t fEmSize; // The size of the em box (defines font units).

View File

@ -0,0 +1,69 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBBHFactory_DEFINED
#define SkBBHFactory_DEFINED
#include "SkSize.h"
#include "SkPoint.h"
class SkBBoxHierarchy;
class SK_API SkBBHFactory {
public:
/**
* Allocate a new SkBBoxHierarchy. Return NULL on failure.
*/
virtual SkBBoxHierarchy* operator()(int width, int height) const = 0;
virtual ~SkBBHFactory() {};
};
class SK_API SkQuadTreeFactory : public SkBBHFactory {
public:
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
private:
typedef SkBBHFactory INHERITED;
};
class SK_API SkRTreeFactory : public SkBBHFactory {
public:
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
private:
typedef SkBBHFactory INHERITED;
};
class SK_API SkTileGridFactory : public SkBBHFactory {
public:
struct TileGridInfo {
/** Tile placement interval */
SkISize fTileInterval;
/** Pixel coverage overlap between adjacent tiles */
SkISize fMargin;
/** Offset added to device-space bounding box positions to convert
* them to tile-grid space. This can be used to adjust the "phase"
* of the tile grid to match probable query rectangles that will be
* used to search into the tile grid. As long as the offset is smaller
* or equal to the margin, there is no need to extend the domain of
* the tile grid to prevent data loss.
*/
SkIPoint fOffset;
};
SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { }
virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE;
private:
TileGridInfo fInfo;
typedef SkBBHFactory INHERITED;
};
#endif

View File

@ -27,7 +27,7 @@ class GrTexture;
/** \class SkBitmap
The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
and height, and a format (config), and a pointer to the actual pixels.
and height, and a format (colortype), and a pointer to the actual pixels.
Bitmaps can be drawn into a SkCanvas, but they are also used to specify the
target of a SkCanvas' drawing operations.
A const SkBitmap exposes getAddr(), which lets a caller write its pixels;
@ -38,6 +38,7 @@ class SK_API SkBitmap {
public:
class SK_API Allocator;
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
enum Config {
kNo_Config, //!< bitmap has not been configured
kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque)
@ -53,9 +54,16 @@ public:
kConfigCount = kARGB_8888_Config + 1
};
/** Return the config for the bitmap. */
Config config() const;
SK_ATTR_DEPRECATED("use config()")
Config getConfig() const { return this->config(); }
#endif
/**
* Default construct creates a bitmap with zero width and height, and no pixels.
* Its config is set to kNo_Config.
* Its colortype is set to kUnknown_SkColorType.
*/
SkBitmap();
@ -88,24 +96,23 @@ public:
SkColorType colorType() const { return fInfo.fColorType; }
SkAlphaType alphaType() const { return fInfo.fAlphaType; }
/** Return the number of bytes per pixel based on the config. If the config
does not have at least 1 byte per (e.g. kA1_Config) then 0 is returned.
/**
* Return the number of bytes per pixel based on the colortype. If the colortype is
* kUnknown_SkColorType, then 0 is returned.
*/
int bytesPerPixel() const { return fInfo.bytesPerPixel(); }
/** Return the rowbytes expressed as a number of pixels (like width and
height). Note, for 1-byte per pixel configs like kA8_Config, this will
return the same as rowBytes(). Is undefined for configs that are less
than 1-byte per pixel (e.g. kA1_Config)
/**
* Return the rowbytes expressed as a number of pixels (like width and height).
* If the colortype is kUnknown_SkColorType, then 0 is returned.
*/
int rowBytesAsPixels() const {
return fRowBytes >> this->shiftPerPixel();
}
/** Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for
2-bytes per pixel configs, 2 for 4-bytes per pixel configs). Return 0
for configs that are not at least 1-byte per pixel (e.g. kA1_Config
or kNo_Config)
/**
* Return the shift amount per pixel (i.e. 0 for 1-byte per pixel, 1 for 2-bytes per pixel
* colortypes, 2 for 4-bytes per pixel colortypes). Return 0 for kUnknown_SkColorType.
*/
int shiftPerPixel() const { return this->bytesPerPixel() >> 1; }
@ -126,19 +133,13 @@ public:
*/
bool drawsNothing() const { return this->empty() || this->isNull(); }
/** Return the config for the bitmap. */
Config config() const;
SK_ATTR_DEPRECATED("use config()")
Config getConfig() const { return this->config(); }
/** Return the number of bytes between subsequent rows of the bitmap. */
size_t rowBytes() const { return fRowBytes; }
/**
* Set the bitmap's alphaType, returning true on success. If false is
* returned, then the specified new alphaType is incompatible with the
* Config, and the current alphaType is unchanged.
* colortype, and the current alphaType is unchanged.
*
* Note: this changes the alphatype for the underlying pixels, which means
* that all bitmaps that might be sharing (subsets of) the pixels will
@ -215,26 +216,6 @@ public:
*/
void reset();
/** Given a config and a width, this computes the optimal rowBytes value. This is called automatically
if you pass 0 for rowBytes to setConfig().
*/
static size_t ComputeRowBytes(Config c, int width);
/** Return the bytes-per-pixel for the specified config. If the config is
not at least 1-byte per pixel, return 0, including for kNo_Config.
*/
static int ComputeBytesPerPixel(Config c);
/** Return the shift-per-pixel for the specified config. If the config is
not at least 1-byte per pixel, return 0, including for kNo_Config.
*/
static int ComputeShiftPerPixel(Config c) {
return ComputeBytesPerPixel(c) >> 1;
}
static int64_t ComputeSize64(Config, int width, int height);
static size_t ComputeSize(Config, int width, int height);
/**
* This will brute-force return true if all of the pixels in the bitmap
* are opaque. If it fails to read the pixels, or encounters an error,
@ -252,27 +233,26 @@ public:
void getBounds(SkRect* bounds) const;
void getBounds(SkIRect* bounds) const;
/** Set the bitmap's config and dimensions. If rowBytes is 0, then
ComputeRowBytes() is called to compute the optimal value. This resets
any pixel/colortable ownership, just like reset().
*/
bool setConfig(Config, int width, int height, size_t rowBytes, SkAlphaType);
bool setConfig(Config config, int width, int height, size_t rowBytes = 0) {
return this->setConfig(config, width, height, rowBytes,
kPremul_SkAlphaType);
}
bool setConfig(const SkImageInfo& info, size_t rowBytes = 0);
bool setInfo(const SkImageInfo&, size_t rowBytes = 0);
/**
* Allocate a pixelref to match the specified image info. If the Factory
* Allocate the bitmap's pixels to match the requested image info. If the Factory
* is non-null, call it to allcoate the pixelref. If the ImageInfo requires
* a colortable, then ColorTable must be non-null, and will be ref'd.
* On failure, the bitmap will be set to empty and return false.
*/
bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*);
/**
* Allocate the bitmap's pixels to match the requested image info and
* rowBytes. If the request cannot be met (e.g. the info is invalid or
* the requested rowBytes are not compatible with the info
* (e.g. rowBytes < info.minRowBytes() or rowBytes is not aligned with
* the pixel size specified by info.colorType()) then false is returned
* and the bitmap is set to empty.
*/
bool allocPixels(const SkImageInfo& info, size_t rowBytes);
/**
* Allocate a pixelref to match the specified image info, using the default
* allocator.
@ -280,15 +260,9 @@ public:
* On failure, the bitmap will be set to empty and return false.
*/
bool allocPixels(const SkImageInfo& info) {
return this->allocPixels(info, NULL, NULL);
return this->allocPixels(info, info.minRowBytes());
}
/**
* Legacy helper function, which creates an SkImageInfo from the specified
* config and then calls allocPixels(info).
*/
bool allocConfigPixels(Config, int width, int height, bool isOpaque = false);
bool allocN32Pixels(int width, int height, bool isOpaque = false) {
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
if (isOpaque) {
@ -300,13 +274,12 @@ public:
/**
* Install a pixelref that wraps the specified pixels and rowBytes, and
* optional ReleaseProc and context. When the pixels are no longer
* referenced, if ReleaseProc is not null, it will be called with the
* referenced, if releaseProc is not null, it will be called with the
* pixels and context as parameters.
* On failure, the bitmap will be set to empty and return false.
*/
bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes,
void (*ReleaseProc)(void* addr, void* context),
void* context);
bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*,
void (*releaseProc)(void* addr, void* context), void* context);
/**
* Call installPixels with no ReleaseProc specified. This means that the
@ -314,7 +287,7 @@ public:
* of the created bitmap (and its pixelRef).
*/
bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
return this->installPixels(info, pixels, rowBytes, NULL, NULL);
return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL);
}
/**
@ -324,20 +297,6 @@ public:
*/
bool installMaskPixels(const SkMask&);
/**
* DEPRECATED: call info().
*/
bool asImageInfo(SkImageInfo* info) const {
// compatibility: return false for kUnknown
if (kUnknown_SkColorType == this->colorType()) {
return false;
}
if (info) {
*info = this->info();
}
return true;
}
/** Use this to assign a new pixel address for an existing bitmap. This
will automatically release any pixelref previously installed. Only call
this if you are handling ownership/lifetime of the pixel memory.
@ -372,7 +331,7 @@ public:
bool preserveDstPad = false) const;
/** Use the standard HeapAllocator to create the pixelref that manages the
pixel memory. It will be sized based on the current width/height/config.
pixel memory. It will be sized based on the current ImageInfo.
If this is called multiple times, a new pixelref object will be created
each time.
@ -380,7 +339,7 @@ public:
not null) it will take care of incrementing the reference count.
@param ctable ColorTable (or null) to use with the pixels that will
be allocated. Only used if config == Index8_Config
be allocated. Only used if colortype == kIndex_8_SkColorType
@return true if the allocation succeeds. If not the pixelref field of
the bitmap will be unchanged.
*/
@ -389,7 +348,7 @@ public:
}
/** Use the specified Allocator to create the pixelref that manages the
pixel memory. It will be sized based on the current width/height/config.
pixel memory. It will be sized based on the current ImageInfo.
If this is called multiple times, a new pixelref object will be created
each time.
@ -397,12 +356,11 @@ public:
not null) it will take care of incrementing the reference count.
@param allocator The Allocator to use to create a pixelref that can
manage the pixel memory for the current
width/height/config. If allocator is NULL, the standard
HeapAllocator will be used.
manage the pixel memory for the current ImageInfo.
If allocator is NULL, the standard HeapAllocator will be used.
@param ctable ColorTable (or null) to use with the pixels that will
be allocated. Only used if config == Index8_Config.
If it is non-null and the config is not Index8, it will
be allocated. Only used if colortype == kIndex_8_SkColorType.
If it is non-null and the colortype is not indexed, it will
be ignored.
@return true if the allocation succeeds. If not the pixelref field of
the bitmap will be unchanged.
@ -466,7 +424,7 @@ public:
bool lockPixelsAreWritable() const;
/** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
it has non-null pixels, and if required by its config, it has a
it has non-null pixels, and if required by its colortype, it has a
non-null colortable. Returns true if all of the above are met.
*/
bool readyToDraw() const {
@ -488,7 +446,7 @@ public:
/** Returns a non-zero, unique value corresponding to the pixels in our
pixelref. Each time the pixels are changed (and notifyPixelsChanged
is called), a different generation ID will be returned. Finally, if
their is no pixelRef then zero is returned.
there is no pixelRef then zero is returned.
*/
uint32_t getGenerationID() const;
@ -500,8 +458,8 @@ public:
/**
* Fill the entire bitmap with the specified color.
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the config only supports
* If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the colortype only supports
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
*/
void eraseColor(SkColor c) const {
@ -511,8 +469,8 @@ public:
/**
* Fill the entire bitmap with the specified color.
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the config only supports
* If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the colortype only supports
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
*/
void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const;
@ -524,8 +482,8 @@ public:
/**
* Fill the specified area of this bitmap with the specified color.
* If the bitmap's config does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the config only supports
* If the bitmap's colortype does not support alpha (e.g. 565) then the alpha
* of the color is ignored (treated as opaque). If the colortype only supports
* alpha (e.g. A1 or A8) then the color's r,g,b components are ignored.
*/
void eraseArea(const SkIRect& area, SkColor c) const;
@ -544,9 +502,8 @@ public:
was scrolled away. E.g. if dx = dy = 0, then inval would
be set to empty. If dx >= width or dy >= height, then
inval would be set to the entire bounds of the bitmap.
@return true if the scroll was doable. Will return false if the bitmap
uses an unsupported config for scrolling (only kA8,
kIndex8, kRGB_565, kARGB_4444, kARGB_8888 are supported).
@return true if the scroll was doable. Will return false if the colortype is kUnkown or
if the bitmap is immutable.
If no pixels are present (i.e. getPixels() returns false)
inval will still be updated, and true will be returned.
*/
@ -555,9 +512,9 @@ public:
/**
* Return the SkColor of the specified pixel. In most cases this will
* require un-premultiplying the color. Alpha only configs (A1 and A8)
* require un-premultiplying the color. Alpha only colortypes (e.g. kAlpha_8_SkColorType)
* return black with the appropriate alpha set. The value is undefined
* for kNone_Config or if x or y are out of bounds, or if the bitmap
* for kUnknown_SkColorType or if x or y are out of bounds, or if the bitmap
* does not have any pixels (or has not be locked with lockPixels()).
*/
SkColor getColor(int x, int y) const;
@ -575,21 +532,21 @@ public:
/** Returns the address of the pixel specified by x,y for 32bit pixels.
* In debug build, this asserts that the pixels are allocated and locked,
* and that the config is 32-bit, however none of these checks are performed
* and that the colortype is 32-bit, however none of these checks are performed
* in the release build.
*/
inline uint32_t* getAddr32(int x, int y) const;
/** Returns the address of the pixel specified by x,y for 16bit pixels.
* In debug build, this asserts that the pixels are allocated and locked,
* and that the config is 16-bit, however none of these checks are performed
* and that the colortype is 16-bit, however none of these checks are performed
* in the release build.
*/
inline uint16_t* getAddr16(int x, int y) const;
/** Returns the address of the pixel specified by x,y for 8bit pixels.
* In debug build, this asserts that the pixels are allocated and locked,
* and that the config is 8-bit, however none of these checks are performed
* and that the colortype is 8-bit, however none of these checks are performed
* in the release build.
*/
inline uint8_t* getAddr8(int x, int y) const;
@ -597,16 +554,16 @@ public:
/** Returns the color corresponding to the pixel specified by x,y for
* colortable based bitmaps.
* In debug build, this asserts that the pixels are allocated and locked,
* that the config is kIndex8, and that the colortable is allocated,
* that the colortype is indexed, and that the colortable is allocated,
* however none of these checks are performed in the release build.
*/
inline SkPMColor getIndex8Color(int x, int y) const;
/** Set dst to be a setset of this bitmap. If possible, it will share the
pixel memory, and just point into a subset of it. However, if the config
pixel memory, and just point into a subset of it. However, if the colortype
does not support this, a local copy will be made and associated with
the dst bitmap. If the subset rectangle, intersected with the bitmap's
dimensions is empty, or if there is an unsupported config, false will be
dimensions is empty, or if there is an unsupported colortype, false will be
returned and dst will be untouched.
@param dst The bitmap that will be set to a subset of this bitmap
@param subset The rectangle of pixels in this bitmap that dst will
@ -619,7 +576,7 @@ public:
* 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).
* alpha, and the requested colortype does not support alpha).
* @param dst The bitmap to be sized and allocated
* @param ct The desired colorType for dst
* @param allocator Allocator used to allocate the pixelref for the dst
@ -633,6 +590,28 @@ public:
return this->copyTo(dst, this->colorType(), allocator);
}
/**
* Copy the bitmap's pixels into the specified buffer (pixels + rowBytes),
* converting them into the requested format (SkImageInfo). The src pixels are read
* starting at the specified (srcX,srcY) offset, relative to the top-left corner.
*
* The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
*
* srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
*
* srcR is intersected with the bounds of the bitmap. If this intersection is not empty,
* then we have two sets of pixels (of equal size). Replace the dst pixels with the
* corresponding src pixels, performing any colortype/alphatype transformations needed
* (in the case where the src and dst have different colortypes or alphatypes).
*
* This call can fail, returning false, for several reasons:
* - If srcR does not intersect the bitmap bounds.
* - If the requested colortype/alphatype cannot be converted from the src's types.
* - If the src pixels are not available.
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY) const;
/**
* Returns true if this bitmap's pixels can be converted into the requested
* colorType, such that copyTo() could succeed.
@ -647,9 +626,6 @@ public:
*/
bool deepCopyTo(SkBitmap* dst) const;
SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint")
void buildMipMap(bool forceRebuild = false);
#ifdef SK_BUILD_FOR_ANDROID
bool hasHardwareMipMap() const {
return (fFlags & kHasHardwareMipMap_Flag) != 0;
@ -689,16 +665,6 @@ public:
bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
SkIPoint* offset) const;
/** The following two functions provide the means to both flatten and
unflatten the bitmap AND its pixels into the provided buffer.
It is recommended that you do not call these functions directly,
but instead call the write/readBitmap functions on the respective
buffers as they can optimize the recording process and avoid recording
duplicate bitmaps and pixelRefs.
*/
void flatten(SkWriteBuffer&) const;
void unflatten(SkReadBuffer&);
SkDEBUGCODE(void validate() const;)
class Allocator : public SkRefCnt {
@ -706,9 +672,9 @@ public:
SK_DECLARE_INST_COUNT(Allocator)
/** Allocate the pixel memory for the bitmap, given its dimensions and
config. Return true on success, where success means either setPixels
colortype. Return true on success, where success means either setPixels
or setPixelRef was called. The pixels need not be locked when this
returns. If the config requires a colortable, it also must be
returns. If the colortype requires a colortable, it also must be
installed via setColorTable. If false is returned, the bitmap and
colortable should be left unchanged.
*/
@ -750,9 +716,6 @@ public:
SK_TO_STRING_NONVIRT()
private:
struct MipMap;
mutable MipMap* fMipMap;
mutable SkPixelRef* fPixelRef;
mutable int fPixelLockCount;
// These are just caches from the locked pixelref
@ -762,9 +725,7 @@ private:
SkIPoint fPixelRefOrigin;
enum Flags {
kImageIsOpaque_Flag = 0x01,
kImageIsVolatile_Flag = 0x02,
kImageIsImmutable_Flag = 0x04,
#ifdef SK_BUILD_FOR_ANDROID
/* A hint for the renderer responsible for drawing this bitmap
* indicating that it should attempt to use mipmaps when this bitmap
@ -782,36 +743,23 @@ private:
void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const;
/* Internal computations for safe size.
*/
static int64_t ComputeSafeSize64(Config config,
uint32_t width,
uint32_t height,
size_t rowBytes);
static size_t ComputeSafeSize(Config config,
uint32_t width,
uint32_t height,
size_t rowBytes);
/* Unreference any pixelrefs or colortables
*/
void freePixels();
void updatePixelsFromRef() const;
static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
void legacyUnflatten(SkReadBuffer&);
/** Given scale factors sx, sy, determine the miplevel available in the
bitmap, and return it (this is the amount to shift matrix iterators
by). If dst is not null, it is set to the correct level.
*/
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
bool hasMipMap() const;
void freeMipMap();
static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&);
static bool ReadRawPixels(SkReadBuffer*, SkBitmap*);
friend class SkBitmapSource; // unflatten
friend class SkReadBuffer; // unflatten, rawpixels
friend class SkWriteBuffer; // rawpixels
friend struct SkBitmapProcState;
};
class SkAutoLockPixels : public SkNoncopyable {
class SkAutoLockPixels : SkNoncopyable {
public:
SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
fDidLock = doLock;
@ -835,7 +783,7 @@ private:
/** Helper class that performs the lock/unlockColors calls on a colortable.
The destructor will call unlockColors(false) if it has a bitmap's colortable
*/
class SkAutoLockColors : public SkNoncopyable {
class SkAutoLockColors : SkNoncopyable {
public:
/** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's
colortable
@ -917,11 +865,13 @@ inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const {
return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)];
}
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
///////////////////////////////////////////////////////////////////////////////
//
// Helpers until we can fully deprecate SkBitmap::Config
//
extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
SK_API SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType);
SK_API SkColorType SkBitmapConfigToColorType(SkBitmap::Config);
#endif
#endif

View File

@ -30,93 +30,12 @@ public:
*/
SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties);
#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
/**
* Create a new raster device and have the pixels be automatically
* allocated. The rowBytes of the device will be computed automatically
* based on the config and the width.
*
* @param config The desired config for the pixels. If the request cannot
* be met, the closest matching support config will be used.
* @param width width (in pixels) of the device
* @param height height (in pixels) of the device
* @param isOpaque Set to true if it is known that all of the pixels will
* be drawn to opaquely. Used as an accelerator when drawing
* these pixels to another device.
*/
SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque = false);
/**
* Create a new raster device and have the pixels be automatically
* allocated. The rowBytes of the device will be computed automatically
* based on the config and the width.
*
* @param config The desired config for the pixels. If the request cannot
* be met, the closest matching support config will be used.
* @param width width (in pixels) of the device
* @param height height (in pixels) of the device
* @param isOpaque Set to true if it is known that all of the pixels will
* be drawn to opaquely. Used as an accelerator when drawing
* these pixels to another device.
* @param deviceProperties Properties which affect compositing.
*/
SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque,
const SkDeviceProperties& deviceProperties);
#endif
static SkBitmapDevice* Create(const SkImageInfo&,
const SkDeviceProperties* = NULL);
/** Return the width of the device (in pixels).
*/
virtual int width() const SK_OVERRIDE { return fBitmap.width(); }
/** Return the height of the device (in pixels).
*/
virtual int height() const SK_OVERRIDE { return fBitmap.height(); }
/** Returns true if the device's bitmap's config treats every pixels as
implicitly opaque.
*/
virtual bool isOpaque() const SK_OVERRIDE { return fBitmap.isOpaque(); }
/** Return the bitmap config of the device's pixels
*/
virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.config(); }
virtual SkImageInfo imageInfo() const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
/**
* DEPRECATED: This will be made protected once WebKit stops using it.
* Instead use Canvas' writePixels method.
*
* Similar to draw sprite, this method will copy the pixels in bitmap onto
* the device, with the top/left corner specified by (x, y). The pixel
* values in the device are completely replaced: there is no blending.
*
* Currently if bitmap is backed by a texture this is a no-op. This may be
* relaxed in the future.
*
* If the bitmap has config kARGB_8888_Config then the config8888 param
* will determines how the pixel valuess are intepreted. If the bitmap is
* not kARGB_8888_Config then this parameter is ignored.
*/
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
SkCanvas::Config8888 config8888) SK_OVERRIDE;
#endif
/**
* Return the device's associated gpu render target, or NULL.
*/
virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; }
protected:
/**
* Device may filter the text flags for drawing text here. If it wants to
* make a change to the specified values, it should write them into the
* textflags parameter (output) and return true. If the paint is fine as
* is, then ignore the textflags parameter and return false.
*
* The baseclass SkDevice filters based on its depth and blitters.
*/
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE;
/** Clears the entire device to the specified color (including alpha).
@ -207,14 +126,7 @@ 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&, int x, int y, SkCanvas::Config8888) SK_OVERRIDE;
virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE;
virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE;
virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes) SK_OVERRIDE;
@ -224,33 +136,6 @@ protected:
virtual void lockPixels() SK_OVERRIDE;
virtual void unlockPixels() SK_OVERRIDE;
/**
* Returns true if the device allows processing of this imagefilter. If
* false is returned, then the filter is ignored. This may happen for
* some subclasses that do not support pixel manipulations after drawing
* has occurred (e.g. printing). The default implementation returns true.
*/
virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
/**
* Override and return true for filters that the device can handle
* intrinsically. Doing so means that SkCanvas will pass-through this
* filter to drawSprite and drawDevice (and potentially filterImage).
* Returning false means the SkCanvas will have apply the filter itself,
* and just pass the resulting image to the device.
*/
virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE;
/**
* Related (but not required) to canHandleImageFilter, this method returns
* true if the device could apply the filter to the src bitmap and return
* the result (and updates offset as needed).
* If the device does not recognize or support this filter,
* it just returns false and leaves result and offset unchanged.
*/
virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&,
SkBitmap* result, SkIPoint* offset) SK_OVERRIDE;
private:
friend class SkCanvas;
friend struct DeviceCM; //for setMatrixClip
@ -266,17 +151,8 @@ private:
// any clip information.
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
// in support of legacy constructors
void init(SkBitmap::Config config, int width, int height, bool isOpaque);
#endif
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE;
/** Causes any deferred drawing to the device to be completed.
*/
virtual void flush() SK_OVERRIDE {}
virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE;
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE;

View File

@ -36,7 +36,7 @@ public:
const SkPMColor* src,
int count, U8CPU alpha, int x, int y);
static Proc Factory(unsigned flags, SkBitmap::Config);
static Proc Factory(unsigned flags, SkColorType);
///////////// D32 version

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBlurTypes_DEFINED
#define SkBlurTypes_DEFINED
#include "SkTypes.h"
enum SkBlurStyle {
kNormal_SkBlurStyle, //!< fuzzy inside and outside
kSolid_SkBlurStyle, //!< solid inside, fuzzy outside
kOuter_SkBlurStyle, //!< nothing inside, fuzzy outside
kInner_SkBlurStyle, //!< fuzzy inside, nothing outside
kLastEnum_SkBlurStyle = kInner_SkBlurStyle
};
enum SkBlurQuality {
kLow_SkBlurQuality, //!< e.g. box filter
kHigh_SkBlurQuality, //!< e.g. 3-pass similar to gaussian
kLastEnum_SkBlurQuality
};
#endif

View File

@ -1,93 +0,0 @@
/*
* Copyright 2006 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 SkBounder_DEFINED
#define SkBounder_DEFINED
#include "SkTypes.h"
#include "SkRefCnt.h"
#include "SkPoint.h"
struct SkGlyph;
struct SkIRect;
struct SkPoint;
struct SkRect;
class SkPaint;
class SkPath;
class SkRegion;
/** \class SkBounder
Base class for intercepting the device bounds of shapes before they are drawn.
Install a subclass of this in your canvas.
*/
class SkBounder : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkBounder)
SkBounder();
/* Call to perform a clip test before calling onIRect.
Returns the result from onIRect.
*/
bool doIRect(const SkIRect&);
bool doIRectGlyph(const SkIRect& , int x, int y, const SkGlyph&);
protected:
/** Override in your subclass. This is called with the device bounds of an
object (text, geometry, image) just before it is drawn. If your method
returns false, the drawing for that shape is aborted. If your method
returns true, drawing continues. The bounds your method receives have already
been transformed in to device coordinates, and clipped to the current clip.
*/
virtual bool onIRect(const SkIRect&) {
return false;
}
/** Passed to onIRectGlyph with the information about the current glyph.
LSB and RSB are fixed-point (16.16) coordinates of the start and end
of the glyph's advance
*/
struct GlyphRec {
SkIPoint fLSB; //!< fixed-point left-side-bearing of the glyph
SkIPoint fRSB; //!< fixed-point right-side-bearing of the glyph
uint16_t fGlyphID;
uint16_t fFlags; //!< currently set to 0
};
/** Optionally, override in your subclass to receive the glyph ID when
text drawing supplies the device bounds of the object.
*/
virtual bool onIRectGlyph(const SkIRect& r, const GlyphRec&) {
return onIRect(r);
}
/** Called after each shape has been drawn. The default implementation does
nothing, but your override could use this notification to signal itself
that the offscreen being rendered into needs to be updated to the screen.
*/
virtual void commit();
private:
bool doHairline(const SkPoint&, const SkPoint&, const SkPaint&);
bool doRect(const SkRect&, const SkPaint&);
bool doPath(const SkPath&, const SkPaint&, bool doFill);
void setClip(const SkRegion* clip) { fClip = clip; }
const SkRegion* fClip;
friend class SkAutoBounderCommit;
friend class SkDraw;
friend class SkDrawIter;
friend struct Draw1Glyph;
friend class SkMaskFilter;
typedef SkRefCnt INHERITED;
};
#endif

View File

@ -18,16 +18,13 @@
#include "SkRegion.h"
#include "SkXfermode.h"
// if not defined, we always assume ClipToLayer for saveLayer()
//#define SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
#ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL
#define SK_LEGACY_DRAWTEXT_VIRTUAL virtual
#else
#define SK_LEGACY_DRAWTEXT_VIRTUAL
#endif
//#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
//#define SK_SUPPORT_LEGACY_GETCLIPTYPE
//#define SK_SUPPORT_LEGACY_GETTOTALCLIP
//#define SK_SUPPORT_LEGACY_GETTOPDEVICE
class SkBounder;
class SkCanvasClipVisitor;
class SkBaseDevice;
class SkDraw;
class SkDrawFilter;
@ -167,7 +164,11 @@ public:
* the bitmap of the pixels that the canvas draws into. The reference count
* of the returned device is not changed by this call.
*/
#ifndef SK_SUPPORT_LEGACY_GETDEVICE
protected: // Can we make this private?
#endif
SkBaseDevice* getDevice() const;
public:
/**
* saveLayer() can create another device (which is later drawn onto
@ -190,7 +191,8 @@ public:
/**
* Create a new surface matching the specified info, one that attempts to
* be maximally compatible when used with this canvas.
* be maximally compatible when used with this canvas. If there is no matching Surface type,
* NULL is returned.
*/
SkSurface* newSurface(const SkImageInfo&);
@ -206,15 +208,14 @@ public:
* If the canvas has writable pixels in its top layer (and is not recording to a picture
* or other non-raster target) and has direct access to its pixels (i.e. they are in
* local RAM) return the address of those pixels, and if not null,
* return the ImageInfo and rowBytes. The returned address is only valid
* return the ImageInfo, rowBytes and origin. The returned address is only valid
* while the canvas object is in scope and unchanged. Any API calls made on
* canvas (or its parent surface if any) will invalidate the
* returned address (and associated information).
*
* On failure, returns NULL and the info and rowBytes parameters are
* ignored.
* On failure, returns NULL and the info, rowBytes, and origin parameters are ignored.
*/
void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes);
void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes, SkIPoint* origin = NULL);
/**
* If the canvas has readable pixels in its base layer (and is not recording to a picture
@ -231,108 +232,42 @@ public:
const void* peekPixels(SkImageInfo* info, size_t* rowBytes);
/**
* 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.
* Copy the pixels from the base-layer into the specified buffer (pixels + rowBytes),
* converting them into the requested format (SkImageInfo). The base-layer pixels are read
* starting at the specified (srcX,srcY) location in the coordinate system of the base-layer.
*
* 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).
* The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle
*
* srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
*
* srcR is intersected with the bounds of the base-layer. If this intersection is not empty,
* then we have two sets of pixels (of equal size). Replace the dst pixels with the
* corresponding src pixels, performing any colortype/alphatype transformations needed
* (in the case where the src and dst have different colortypes or alphatypes).
*
* This call can fail, returning false, for several reasons:
* - If srcR does not intersect the base-layer bounds.
* - If the requested colortype/alphatype cannot be converted from the base-layer's types.
* - If this canvas is not backed by pixels (e.g. picture or PDF)
*/
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
};
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY);
/**
* 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
* }
* Helper for calling readPixels(info, ...). This call will check if bitmap has been allocated.
* If not, it will attempt to call allocPixels(). If this fails, it will return false. If not,
* it calls through to readPixels(info, ...) and returns its result.
*/
bool readPixels(SkBitmap* bitmap,
int x, int y,
Config8888 config8888 = kNative_Premul_Config8888);
bool readPixels(SkBitmap* bitmap, int srcX, int srcY);
/**
* 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.
* Helper for allocating pixels and then calling readPixels(info, ...). The bitmap is resized
* to the intersection of srcRect and the base-layer bounds. On success, pixels will be
* allocated in bitmap and true returned. On failure, false is returned and bitmap will be
* set to empty.
*/
bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap);
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
/**
* DEPRECATED
* Similar to draw sprite, this method will copy the pixels in bitmap onto
* 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, Config8888 config8888);
#endif
/**
* This method affects the pixels in the base-layer, and operates in pixel coordinates,
* ignoring the matrix and clip.
@ -363,8 +298,10 @@ public:
enum SaveFlags {
/** save the matrix state, restoring it on restore() */
// [deprecated] kMatrix_SaveFlag = 0x01,
kMatrix_SaveFlag = 0x01,
/** save the clip state, restoring it on restore() */
// [deprecated] kClip_SaveFlag = 0x02,
kClip_SaveFlag = 0x02,
/** the layer needs to support per-pixel alpha */
kHasAlphaLayer_SaveFlag = 0x04,
@ -378,6 +315,7 @@ public:
kClipToLayer_SaveFlag = 0x10,
// helper masks for common choices
// [deprecated] kMatrixClip_SaveFlag = 0x03,
kMatrixClip_SaveFlag = 0x03,
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
kARGB_NoClipLayer_SaveFlag = 0x0F,
@ -391,20 +329,31 @@ public:
operate on this copy.
When the balancing call to restore() is made, the previous matrix, clip,
and drawFilter are restored.
@param flags The flags govern what portion of the Matrix/Clip/drawFilter
state the save (and matching restore) effect. For example,
if only kMatrix is specified, then only the matrix state
will be pushed and popped. Likewise for the clip if kClip
is specified. However, the drawFilter is always affected
by calls to save/restore.
@return The value to pass to restoreToCount() to balance this save()
*/
int save(SaveFlags flags = kMatrixClip_SaveFlag);
int save();
/** This behaves the same as save(), but in addition it allocates an
offscreen bitmap. All drawing calls are directed there, and only when
the balancing call to restore() is made is that offscreen transfered to
the canvas (or the previous layer).
@param bounds (may be null) This rect, if non-null, is used as a hint to
limit the size of the offscreen, and thus drawing may be
clipped to it, though that clipping is not guaranteed to
happen. If exact clipping is desired, use clipRect().
@param paint (may be null) This is copied, and is applied to the
offscreen when restore() is called
@return The value to pass to restoreToCount() to balance this save()
*/
int saveLayer(const SkRect* bounds, const SkPaint* paint);
/** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead.
This behaves the same as saveLayer(const SkRect*, const SkPaint*),
but it allows fine-grained control of which state bits to be saved
(and subsequently restored).
@param bounds (may be null) This rect, if non-null, is used as a hint to
limit the size of the offscreen, and thus drawing may be
clipped to it, though that clipping is not guaranteed to
@ -414,13 +363,28 @@ public:
@param flags LayerFlags
@return The value to pass to restoreToCount() to balance this save()
*/
int saveLayer(const SkRect* bounds, const SkPaint* paint,
SaveFlags flags = kARGB_ClipLayer_SaveFlag);
SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
/** This behaves the same as save(), but in addition it allocates an
offscreen bitmap. All drawing calls are directed there, and only when
the balancing call to restore() is made is that offscreen transfered to
the canvas (or the previous layer).
@param bounds (may be null) This rect, if non-null, is used as a hint to
limit the size of the offscreen, and thus drawing may be
clipped to it, though that clipping is not guaranteed to
happen. If exact clipping is desired, use clipRect().
@param alpha This is applied to the offscreen when restore() is called.
@return The value to pass to restoreToCount() to balance this save()
*/
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
/** DEPRECATED - use saveLayerAlpha(const SkRect*, U8CPU) instead.
This behaves the same as saveLayerAlpha(const SkRect*, U8CPU),
but it allows fine-grained control of which state bits to be saved
(and subsequently restored).
@param bounds (may be null) This rect, if non-null, is used as a hint to
limit the size of the offscreen, and thus drawing may be
clipped to it, though that clipping is not guaranteed to
@ -429,8 +393,8 @@ public:
@param flags LayerFlags
@return The value to pass to restoreToCount() to balance this save()
*/
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha,
SaveFlags flags = kARGB_ClipLayer_SaveFlag);
SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, SaveFlags flags);
/** This call balances a previous call to save(), and is used to remove all
modifications to the matrix/clip/drawFilter state since the last save
@ -461,35 +425,30 @@ public:
/** Preconcat the current matrix with the specified translation
@param dx The distance to translate in X
@param dy The distance to translate in Y
returns true if the operation succeeded (e.g. did not overflow)
*/
bool translate(SkScalar dx, SkScalar dy);
void translate(SkScalar dx, SkScalar dy);
/** Preconcat the current matrix with the specified scale.
@param sx The amount to scale in X
@param sy The amount to scale in Y
returns true if the operation succeeded (e.g. did not overflow)
*/
bool scale(SkScalar sx, SkScalar sy);
void scale(SkScalar sx, SkScalar sy);
/** Preconcat the current matrix with the specified rotation.
@param degrees The amount to rotate, in degrees
returns true if the operation succeeded (e.g. did not overflow)
*/
bool rotate(SkScalar degrees);
void rotate(SkScalar degrees);
/** Preconcat the current matrix with the specified skew.
@param sx The amount to skew in X
@param sy The amount to skew in Y
returns true if the operation succeeded (e.g. did not overflow)
*/
bool skew(SkScalar sx, SkScalar sy);
void skew(SkScalar sx, SkScalar sy);
/** Preconcat the current matrix with the specified matrix.
@param matrix The matrix to preconcatenate with the current matrix
@return true if the operation succeeded (e.g. did not overflow)
*/
bool concat(const SkMatrix& matrix);
void concat(const SkMatrix& matrix);
/** Replace the current matrix with a copy of the specified matrix.
@param matrix The matrix that will be copied into the current matrix.
@ -669,6 +628,20 @@ public:
*/
virtual void clear(SkColor);
/**
* This makes the contents of the canvas undefined. Subsequent calls that
* require reading the canvas contents will produce undefined results. Examples
* include blending and readPixels. The actual implementation is backend-
* dependent and one legal implementation is to do nothing. Like clear(), this
* ignores the clip.
*
* This function should only be called if the caller intends to subsequently
* draw to the canvas. The canvas may do real work at discard() time in order
* to optimize performance on subsequent draws. Thus, if you call this and then
* never draw to the canvas subsequently you may pay a perfomance penalty.
*/
void discard() { this->onDiscard(); }
/**
* Fill the entire canvas' bitmap (restricted to the current clip) with the
* specified paint.
@ -834,7 +807,7 @@ public:
width/height will be the edge color replicated.
If a shader is present on the paint it will be ignored, except in the
case where the bitmap is kA8_Config. In that case, the color is
case where the bitmap is kAlpha_8_SkColorType. In that case, the color is
generated by the shader.
@param bitmap The bitmap to be drawn
@ -927,7 +900,7 @@ public:
@param y The y-coordinate of the origin of the text being drawn
@param paint The paint used for the text (e.g. color, size, style)
*/
virtual void drawText(const void* text, size_t byteLength, SkScalar x,
SK_LEGACY_DRAWTEXT_VIRTUAL void drawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint);
/** Draw the text, with each character/glyph origin specified by the pos[]
@ -937,7 +910,7 @@ public:
@param pos Array of positions, used to position each character
@param paint The paint used for the text (e.g. color, size, style)
*/
virtual void drawPosText(const void* text, size_t byteLength,
SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint);
/** Draw the text, with each character/glyph origin specified by the x
@ -949,7 +922,7 @@ public:
@param constY The shared Y coordinate for all of the positions
@param paint The paint used for the text (e.g. color, size, style)
*/
virtual void drawPosTextH(const void* text, size_t byteLength,
SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint);
@ -979,7 +952,7 @@ public:
mapped onto the path
@param paint The paint used for the text
*/
virtual void drawTextOnPath(const void* text, size_t byteLength,
SK_LEGACY_DRAWTEXT_VIRTUAL void drawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
@ -989,7 +962,7 @@ public:
drawPicture call.
@param picture The recorded drawing commands to analyze/optimize
*/
void EXPERIMENTAL_optimize(SkPicture* picture);
void EXPERIMENTAL_optimize(const SkPicture* picture);
/** Draw the picture into this canvas. This method effective brackets the
playback of the picture's draw calls with save/restore, so the state
@ -997,7 +970,7 @@ public:
@param picture The recorded drawing commands to playback into this
canvas.
*/
virtual void drawPicture(SkPicture& picture);
void drawPicture(const SkPicture* picture);
enum VertexMode {
kTriangles_VertexMode,
@ -1006,6 +979,11 @@ public:
};
/** Draw the array of vertices, interpreted as triangles (based on mode).
If both textures and vertex-colors are NULL, it strokes hairlines with
the paint's color. This behavior is a useful debugging mode to visualize
the mesh.
@param vmode How to interpret the array of vertices
@param vertexCount The number of points in the vertices array (and
corresponding texs and colors arrays if non-null)
@ -1059,38 +1037,15 @@ public:
* is not enforced, but the information might be used to quick-reject command blocks,
* so an incorrect bounding box may result in incomplete rendering.
*/
void pushCull(const SkRect& cullRect) {
++fCullCount;
this->onPushCull(cullRect);
}
void pushCull(const SkRect& cullRect);
/**
* Terminates the current culling block, and restores the previous one (if any).
*/
void popCull() {
if (fCullCount > 0) {
--fCullCount;
this->onPopCull();
}
}
void popCull();
//////////////////////////////////////////////////////////////////////////
/** Get the current bounder object.
The bounder's reference count is unchaged.
@return the canva's bounder (or NULL).
*/
SkBounder* getBounder() const { return fBounder; }
/** Set a new bounder (or NULL).
Pass NULL to clear any previous bounder.
As a convenience, the parameter passed is also returned.
If a previous bounder exists, its reference count is decremented.
If bounder is not NULL, its reference count is incremented.
@param bounder the new bounder (or NULL) to be installed in the canvas
@return the set bounder object
*/
virtual SkBounder* setBounder(SkBounder* bounder);
/** Get the current filter object. The filter's reference count is not
affected. The filter is saved/restored, just like the matrix and clip.
@return the canvas' filter (or NULL).
@ -1142,15 +1097,6 @@ public:
virtual ClipType getClipType() const;
#endif
#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP
/** DEPRECATED -- need to move this guy to private/friend
* Return the current device clip (concatenation of all clip calls).
* This does not account for the translate in any of the devices.
* @return the current device clip (concatenation of all clip calls).
*/
const SkRegion& getTotalClip() const;
#endif
/** Return the clip stack. The clip stack stores all the individual
* clips organized by the save/restore frame in which they were
* added.
@ -1160,14 +1106,7 @@ public:
return &fClipStack;
}
class ClipVisitor {
public:
virtual ~ClipVisitor();
virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
};
typedef SkCanvasClipVisitor ClipVisitor;
/**
* Replays the clip operations, back to front, that have been applied to
* the canvas, calling the appropriate method on the visitor for each
@ -1237,19 +1176,31 @@ protected:
kFullLayer_SaveLayerStrategy,
kNoLayer_SaveLayerStrategy
};
virtual void willSave(SaveFlags);
virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags);
virtual void willRestore();
virtual void didTranslate(SkScalar, SkScalar);
virtual void didScale(SkScalar, SkScalar);
virtual void didRotate(SkScalar);
virtual void didSkew(SkScalar, SkScalar);
virtual void didConcat(const SkMatrix&);
virtual void didSetMatrix(const SkMatrix&);
virtual void willSave() {}
virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
return kFullLayer_SaveLayerStrategy;
}
virtual void willRestore() {}
virtual void didConcat(const SkMatrix&) {}
virtual void didSetMatrix(const SkMatrix&) {}
virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
virtual void onDrawText(const void* text, size_t byteLength, SkScalar x,
SkScalar y, const SkPaint& paint);
virtual void onDrawPosText(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint);
virtual void onDrawPosTextH(const void* text, size_t byteLength,
const SkScalar xpos[], SkScalar constY,
const SkPaint& paint);
virtual void onDrawTextOnPath(const void* text, size_t byteLength,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
enum ClipEdgeStyle {
kHard_ClipEdgeStyle,
kSoft_ClipEdgeStyle
@ -1260,6 +1211,10 @@ protected:
virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle);
virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op);
virtual void onDiscard();
virtual void onDrawPicture(const SkPicture* picture);
// Returns the canvas to be used by DrawIter. Default implementation
// returns this. Subclasses that encapsulate an indirect canvas may
// need to overload this method. The impl must keep track of this, as it
@ -1296,7 +1251,6 @@ private:
// the first N recs that can fit here mean we won't call malloc
uint32_t fMCRecStorage[32];
SkBounder* fBounder;
int fSaveLayerCount; // number of successful saveLayer calls
int fCullCount; // number of active culls
@ -1316,7 +1270,9 @@ private:
friend class SkDrawIter; // needs setupDrawForLayerDevice()
friend class AutoDrawLooper;
friend class SkLua; // needs top layer size and offset
friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip
friend class SkDeferredDevice; // needs getTopDevice()
friend class SkSurface_Raster; // needs getDevice()
SkBaseDevice* createLayerDevice(const SkImageInfo&);
@ -1352,7 +1308,7 @@ private:
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*);
// shared by save() and saveLayer()
int internalSave(SaveFlags flags);
int internalSave();
void internalRestore();
static void DrawRect(const SkDraw& draw, const SkPaint& paint,
const SkRect& r, SkScalar textSize);
@ -1390,6 +1346,9 @@ private:
};
#ifdef SK_DEBUG
// The cull stack rects are in device-space
SkTDArray<SkIRect> fCullStack;
void validateCull(const SkIRect&);
void validateClip() const;
#else
void validateClip() const {}
@ -1500,4 +1459,23 @@ private:
size_t fRowBytes;
};
static inline SkCanvas::SaveFlags operator|(const SkCanvas::SaveFlags lhs,
const SkCanvas::SaveFlags rhs) {
return static_cast<SkCanvas::SaveFlags>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
static inline SkCanvas::SaveFlags& operator|=(SkCanvas::SaveFlags& lhs,
const SkCanvas::SaveFlags rhs) {
lhs = lhs | rhs;
return lhs;
}
class SkCanvasClipVisitor {
public:
virtual ~SkCanvasClipVisitor();
virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0;
virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
};
#endif

View File

@ -16,6 +16,7 @@
#include "SkTDArray.h"
#include "SkTLazy.h"
class SkCanvasClipVisitor;
// Because a single save/restore state can have multiple clips, this class
// stores the stack depth (fSaveCount) and clips (fDeque) separately.
@ -47,7 +48,10 @@ public:
kRRect_Type,
//!< This element combines a path with the current clip using a set operation
kPath_Type,
kLastType = kPath_Type
};
static const int kTypeCnt = kLastType + 1;
Element() {
this->initCommon(0, SkRegion::kReplace_Op, false);
@ -74,6 +78,9 @@ public:
//!< Call to get the type of the clip element.
Type getType() const { return fType; }
//!< Call to get the save count associated with this clip element.
int getSaveCount() const { return fSaveCount; }
//!< Call if getType() is kPath to get the path.
const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); }
@ -156,6 +163,19 @@ public:
return kPath_Type == fType && fPath.get()->isInverseFillType();
}
/**
* Replay this clip into the visitor.
*/
void replay(SkCanvasClipVisitor*) const;
#ifdef SK_DEVELOPER
/**
* Dumps the element to SkDebugf. This is intended for Skia development debugging
* Don't rely on the existence of this function or the formatting of its output.
*/
void dump() const;
#endif
private:
friend class SkClipStack;
@ -332,6 +352,14 @@ public:
int32_t getTopmostGenID() const;
#ifdef SK_DEVELOPER
/**
* Dumps the contents of the clip stack to SkDebugf. This is intended for Skia development
* debugging. Don't rely on the existence of this function or the formatting of its output.
*/
void dump() const;
#endif
public:
class Iter {
public:

View File

@ -15,7 +15,7 @@
#include "SkXfermode.h"
class SkBitmap;
class GrEffectRef;
class GrEffect;
class GrContext;
/**
@ -126,7 +126,7 @@ public:
/** A subclass may implement this factory function to work with the GPU backend. If the return
is non-NULL then the caller owns a ref on the returned object.
*/
virtual GrEffectRef* asNewEffect(GrContext*) const;
virtual GrEffect* asNewEffect(GrContext*) const;
SK_TO_STRING_PUREVIRT()

View File

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkColorPriv_DEFINED
#define SkColorPriv_DEFINED
@ -18,6 +16,134 @@
#include "SkColor.h"
#include "SkMath.h"
//////////////////////////////////////////////////////////////////////////////
#define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF))
/*
* Skia's 32bit backend only supports 1 sizzle order at a time (compile-time).
* This is specified by 4 defines SK_A32_SHIFT, SK_R32_SHIFT, ... for G and B.
*
* For easier compatibility with Skia's GPU backend, we further restrict these
* to either (in memory-byte-order) RGBA or BGRA. Note that this "order" does
* not directly correspond to the same shift-order, since we have to take endianess
* into account.
*
* Here we enforce this constraint.
*/
#ifdef SK_CPU_BENDIAN
#define SK_RGBA_R32_SHIFT 24
#define SK_RGBA_G32_SHIFT 16
#define SK_RGBA_B32_SHIFT 8
#define SK_RGBA_A32_SHIFT 0
#define SK_BGRA_B32_SHIFT 24
#define SK_BGRA_G32_SHIFT 16
#define SK_BGRA_R32_SHIFT 8
#define SK_BGRA_A32_SHIFT 0
#else
#define SK_RGBA_R32_SHIFT 0
#define SK_RGBA_G32_SHIFT 8
#define SK_RGBA_B32_SHIFT 16
#define SK_RGBA_A32_SHIFT 24
#define SK_BGRA_B32_SHIFT 0
#define SK_BGRA_G32_SHIFT 8
#define SK_BGRA_R32_SHIFT 16
#define SK_BGRA_A32_SHIFT 24
#endif
#if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)
#error "can't define PMCOLOR to be RGBA and BGRA"
#endif
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \
(SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \
SK_B32_SHIFT == SK_RGBA_B32_SHIFT)
#define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \
(SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \
SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \
SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \
SK_B32_SHIFT == SK_BGRA_B32_SHIFT)
#if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values"
#endif
#if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
#error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
#endif
#if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
// deduce which to define from the _SHIFT defines
#if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#define SK_PMCOLOR_IS_RGBA
#elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
#define SK_PMCOLOR_IS_BGRA
#else
#error "need 32bit packing to be either RGBA or BGRA"
#endif
#endif
// hide these now that we're done
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
#undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
//////////////////////////////////////////////////////////////////////////////
// Reverse the bytes coorsponding to RED and BLUE in a packed pixels. Note the
// pair of them are in the same 2 slots in both RGBA and BGRA, thus there is
// no need to pass in the colortype to this function.
static inline uint32_t SkSwizzle_RB(uint32_t c) {
static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT);
unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF;
unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF;
return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT);
}
static inline uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkASSERT_IS_BYTE(a);
SkASSERT_IS_BYTE(r);
SkASSERT_IS_BYTE(g);
SkASSERT_IS_BYTE(b);
return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) |
(g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT);
}
static inline uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
SkASSERT_IS_BYTE(a);
SkASSERT_IS_BYTE(r);
SkASSERT_IS_BYTE(g);
SkASSERT_IS_BYTE(b);
return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) |
(g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
}
static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) {
#ifdef SK_PMCOLOR_IS_RGBA
return c;
#else
return SkSwizzle_RB(c);
#endif
}
static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) {
#ifdef SK_PMCOLOR_IS_BGRA
return c;
#else
return SkSwizzle_RB(c);
#endif
}
//////////////////////////////////////////////////////////////////////////////
///@{
/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/
#define SK_ITU_BT709_LUM_COEFF_R (0.2126f)
@ -55,6 +181,15 @@ static inline unsigned SkAlpha255To256(U8CPU alpha) {
return alpha + 1;
}
/**
* Turn a 0..255 value into a 0..256 value, rounding up if the value is >= 0x80.
* This is slightly more accurate than SkAlpha255To256.
*/
static inline unsigned Sk255To256(U8CPU value) {
SkASSERT(SkToU8(value) == value);
return value + (value >> 7);
}
/** Multiplify value by 0..256, and shift the result down 8
(i.e. return (value * alpha256) >> 8)
*/
@ -239,6 +374,16 @@ static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
(g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
}
static inline uint32_t SkPackPMColor_as_RGBA(SkPMColor c) {
return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c),
SkGetPackedG32(c), SkGetPackedB32(c));
}
static inline uint32_t SkPackPMColor_as_BGRA(SkPMColor c) {
return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c),
SkGetPackedG32(c), SkGetPackedB32(c));
}
/**
* Abstract 4-byte interpolation, implemented on top of SkPMColor
* utility functions. Third parameter controls blending of the first two:
@ -379,10 +524,10 @@ SkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
return SkPackARGB32(a, r, g, b);
}
SK_API extern const uint32_t gMask_00FF00FF;
static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
uint32_t mask = gMask_00FF00FF;
// When Android is compiled optimizing for size, SkAlphaMulQ doesn't get
// inlined; forcing inlining significantly improves performance.
static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
uint32_t mask = 0xFF00FF;
uint32_t rb = ((c & mask) * scale) >> 8;
uint32_t ag = ((c >> 8) & mask) * scale;
@ -642,8 +787,6 @@ static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
(g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
}
extern const uint16_t gMask_0F0F;
static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
SkASSERT(scale <= 16);

View File

@ -19,27 +19,35 @@
*/
class SK_API SkColorShader : public SkShader {
public:
/** Create a ColorShader that will inherit its color from the Paint
at draw time.
*/
SkColorShader();
/** Create a ColorShader that ignores the color in the paint, and uses the
specified color. Note: like all shaders, at draw time the paint's alpha
will be respected, and is applied to the specified color.
*/
SkColorShader(SkColor c);
explicit SkColorShader(SkColor c);
virtual ~SkColorShader();
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) 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;
virtual size_t contextSize() const SK_OVERRIDE {
return sizeof(ColorShaderContext);
}
class ColorShaderContext : public SkShader::Context {
public:
ColorShaderContext(const SkColorShader& shader, const ContextRec&);
virtual uint32_t getFlags() const SK_OVERRIDE;
virtual uint8_t getSpan16Alpha() const 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;
private:
SkPMColor fPMColor;
uint32_t fFlags;
uint16_t fColor16;
typedef SkShader::Context INHERITED;
};
// we return false for this, use asAGradient
virtual BitmapType asABitmap(SkBitmap* outTexture,
@ -48,20 +56,20 @@ public:
virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
const SkMatrix* localMatrix, GrColor* paintColor,
GrEffect** effect) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader)
protected:
SkColorShader(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual Context* onCreateContext(const ContextRec&, void* storage) const SK_OVERRIDE;
private:
SkColor fColor; // ignored if fInheritColor is true
SkPMColor fPMColor; // cached after setContext()
uint32_t fFlags; // cached after setContext()
uint16_t fColor16; // cached after setContext()
SkBool8 fInheritColor;
typedef SkShader INHERITED;
};

View File

@ -17,14 +17,14 @@ class SkXfermode;
///////////////////////////////////////////////////////////////////////////////////////////
/** \class SkComposeShader
This subclass of shader returns the coposition of two other shaders, combined by
This subclass of shader returns the composition of two other shaders, combined by
a xfermode.
*/
class SK_API SkComposeShader : public SkShader {
public:
/** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
When the xfermode is called, it will be given the result from shader A as its
"dst", and the result of from shader B as its "src".
"dst", and the result from shader B as its "src".
mode->xfer32(sA_result, sB_result, ...)
@param shaderA The colors from this shader are seen as the "dst" by the xfermode
@param shaderB The colors from this shader are seen as the "src" by the xfermode
@ -34,10 +34,35 @@ public:
SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL);
virtual ~SkComposeShader();
virtual bool setContext(const SkBitmap&, const SkPaint&,
const SkMatrix&) SK_OVERRIDE;
virtual void endContext() SK_OVERRIDE;
virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
virtual size_t contextSize() const SK_OVERRIDE;
class ComposeShaderContext : public SkShader::Context {
public:
// When this object gets destroyed, it will call contextA and contextB's destructor
// but it will NOT free the memory.
ComposeShaderContext(const SkComposeShader&, const ContextRec&,
SkShader::Context* contextA, SkShader::Context* contextB);
SkShader::Context* getShaderContextA() const { return fShaderContextA; }
SkShader::Context* getShaderContextB() const { return fShaderContextB; }
virtual ~ComposeShaderContext();
virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE;
private:
SkShader::Context* fShaderContextA;
SkShader::Context* fShaderContextB;
typedef SkShader::Context INHERITED;
};
#ifdef SK_DEBUG
SkShader* getShaderA() { return fShaderA; }
SkShader* getShaderB() { return fShaderB; }
#endif
virtual bool asACompose(ComposeRec* rec) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader)
@ -45,9 +70,9 @@ public:
protected:
SkComposeShader(SkReadBuffer& );
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE;
private:
SkShader* fShaderA;
SkShader* fShaderB;
SkXfermode* fMode;

View File

@ -137,7 +137,8 @@ private:
virtual ~SkData();
// Called the first time someone calls NewEmpty to initialize the singleton.
static void NewEmptyImpl(int/*unused*/);
static SkData* NewEmptyImpl();
static void DeleteEmpty(SkData*);
typedef SkRefCnt INHERITED;
};

View File

@ -1,4 +1,3 @@
/*
* Copyright 2010 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkDevice_DEFINED
#define SkDevice_DEFINED
@ -17,13 +15,6 @@
#include "SkDeviceProperties.h"
#include "SkImageFilter.h"
// getDeviceCapabilities() is not called by skia, but this flag keeps it around
// for clients that have "override" annotations on their subclass. These overrides
// should be deleted.
//#define SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES
//#define SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
class SkClipStack;
class SkDraw;
struct SkIRect;
@ -49,40 +40,10 @@ public:
virtual ~SkBaseDevice();
#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
/**
* Creates a device that is of the same type as this device (e.g. SW-raster,
* GPU, or PDF). The backing store for this device is created automatically
* (e.g. offscreen pixels or FBO or whatever is appropriate).
*
* @param width width of the device to create
* @param height height of the device to create
* @param isOpaque performance hint, set to true if you know that you will
* draw into this device such that all of the pixels will
* be opaque.
*/
SkBaseDevice* createCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque);
#endif
SkBaseDevice* createCompatibleDevice(const SkImageInfo&);
SkMetaData& getMetaData();
#ifdef SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES
enum Capabilities {
kVector_Capability = 0x1,
};
virtual uint32_t getDeviceCapabilities() { return 0; }
#endif
/** Return the width of the device (in pixels).
*/
virtual int width() const = 0;
/** Return the height of the device (in pixels).
*/
virtual int height() const = 0;
/** Return the image properties of the device. */
virtual const SkDeviceProperties& getDeviceProperties() const {
//Currently, all the properties are leaky.
@ -106,15 +67,17 @@ public:
bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height());
}
int width() const {
return this->imageInfo().width();
}
/** Returns true if the device's bitmap's config treats every pixel as
implicitly opaque.
*/
virtual bool isOpaque() const = 0;
int height() const {
return this->imageInfo().height();
}
/** Return the bitmap config of the device's pixels
*/
virtual SkBitmap::Config config() const = 0;
bool isOpaque() const {
return this->imageInfo().isOpaque();
}
/** Return the bitmap associated with this device. Call this each time you need
to access the bitmap, as it notifies the subclass to perform any flushing
@ -124,34 +87,14 @@ public:
*/
const SkBitmap& accessBitmap(bool changePixels);
#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG
/**
* DEPRECATED: This will be made protected once WebKit stops using it.
* Instead use Canvas' writePixels method.
*
* Similar to draw sprite, this method will copy the pixels in bitmap onto
* the device, with the top/left corner specified by (x, y). The pixel
* values in the device are completely replaced: there is no blending.
*
* Currently if bitmap is backed by a texture this is a no-op. This may be
* relaxed in the future.
*
* If the bitmap has config kARGB_8888_Config then the config8888 param
* will determines how the pixel valuess are intepreted. If the bitmap is
* not kARGB_8888_Config then this parameter is ignored.
*/
virtual void writePixels(const SkBitmap& bitmap, int x, int y,
SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888);
#endif
bool writePixelsDirect(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y);
void* accessPixels(SkImageInfo* info, size_t* rowBytes);
/**
* Return the device's associated gpu render target, or NULL.
*/
virtual GrRenderTarget* accessRenderTarget() = 0;
virtual GrRenderTarget* accessRenderTarget() { return NULL; }
/**
@ -204,10 +147,8 @@ protected:
* make a change to the specified values, it should write them into the
* textflags parameter (output) and return true. If the paint is fine as
* is, then ignore the textflags parameter and return false.
*
* The baseclass SkBaseDevice filters based on its depth and blitters.
*/
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) = 0;
virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) { return false; }
/**
*
@ -307,36 +248,7 @@ protected:
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
const SkPaint&) = 0;
/**
* On success (returns true), copy the device pixels into the bitmap.
* On failure, the bitmap parameter is left unchanged and false is
* returned.
*
* The device's pixels are converted to the bitmap's config. The only
* supported config is kARGB_8888_Config, though this is likely to be
* relaxed in the future. The meaning of config kARGB_8888_Config is
* modified by the enum param config8888. The default value interprets
* kARGB_8888_Config as SkPMColor
*
* If the bitmap has pixels already allocated, the device pixels will be
* written there. If not, bitmap->allocPixels() will be called
* automatically. If the bitmap is backed by a texture readPixels will
* fail.
*
* The actual pixels written is the intersection of the device's bounds,
* and the rectangle formed by the bitmap's width,height and the specified
* x,y. If bitmap pixels extend outside of that intersection, they will not
* be modified.
*
* Other failure conditions:
* * If the device is not a raster device (e.g. PDF) then readPixels will
* fail.
* * If bitmap is texture-backed then readPixels will fail. (This may be
* relaxed in the future.)
*/
bool readPixels(SkBitmap* bitmap,
int x, int y,
SkCanvas::Config8888 config8888);
bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
///////////////////////////////////////////////////////////////////////////
@ -349,8 +261,8 @@ protected:
/** Called when this device is installed into a Canvas. Balanced by a call
to unlockPixels() when the device is removed from a Canvas.
*/
virtual void lockPixels() = 0;
virtual void unlockPixels() = 0;
virtual void lockPixels() {}
virtual void unlockPixels() {}
/**
* Returns true if the device allows processing of this imagefilter. If
@ -358,7 +270,7 @@ protected:
* some subclasses that do not support pixel manipulations after drawing
* has occurred (e.g. printing). The default implementation returns true.
*/
virtual bool allowImageFilter(const SkImageFilter*) = 0;
virtual bool allowImageFilter(const SkImageFilter*) { return true; }
/**
* Override and return true for filters that the device can handle
@ -367,7 +279,7 @@ protected:
* Returning false means the SkCanvas will have apply the filter itself,
* and just pass the resulting image to the device.
*/
virtual bool canHandleImageFilter(const SkImageFilter*) = 0;
virtual bool canHandleImageFilter(const SkImageFilter*) { return false; }
/**
* Related (but not required) to canHandleImageFilter, this method returns
@ -378,11 +290,9 @@ protected:
*/
virtual bool filterImage(const SkImageFilter*, const SkBitmap&,
const SkImageFilter::Context& ctx,
SkBitmap* result, SkIPoint* offset) = 0;
// This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if
// either is identical to kNative_Premul_Config8888. Otherwise, -1.
static const SkCanvas::Config8888 kPMColorAlias;
SkBitmap* result, SkIPoint* offset) {
return false;
}
protected:
// default impl returns NULL
@ -392,15 +302,12 @@ protected:
virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes);
/**
* 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.
* The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst
* image at the specified x,y offset will fit within the device's bounds.
*
* This is explicitly asserted in readPixels(), the public way to call this.
*/
virtual bool onReadPixels(const SkBitmap& bitmap,
int x, int y,
SkCanvas::Config8888 config8888);
virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y);
/**
* The caller is responsible for "pre-clipping" the src. The impl can assume that the src
@ -427,7 +334,7 @@ protected:
* PRIVATE / EXPERIMENTAL -- do not call
* Construct an acceleration object and attach it to 'picture'
*/
virtual void EXPERIMENTAL_optimize(SkPicture* picture);
virtual void EXPERIMENTAL_optimize(const SkPicture* picture);
/**
* PRIVATE / EXPERIMENTAL -- do not call
@ -439,7 +346,7 @@ protected:
* to perform some device-specific warm up tasks and then let SkCanvas
* perform the main rendering loop (by return false from here).
*/
virtual bool EXPERIMENTAL_drawPicture(const SkPicture& picture);
virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture);
private:
friend class SkCanvas;
@ -456,32 +363,20 @@ private:
// but cannot change the width/height, so there should be no change to
// any clip information.
// TODO: move to SkBitmapDevice
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) = 0;
virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {}
// just called by SkCanvas when built as a layer
void setOrigin(int x, int y) { fOrigin.set(x, y); }
// just called by SkCanvas for saveLayer
SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&);
#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG
/**
* Justs exists during the period where clients still "override" this
* signature. They are supported by our base-impl calling this old
* signature from the new one (using ImageInfo).
*/
virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque, Usage) {
return NULL;
}
#endif
virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) {
return NULL;
}
/** Causes any deferred drawing to the device to be completed.
*/
virtual void flush() = 0;
virtual void flush() {}
SkIPoint fOrigin;
SkMetaData* fMetaData;

View File

@ -1,15 +1,6 @@
#ifndef SkDeviceProperties_DEFINED
#define SkDeviceProperties_DEFINED
#ifndef SK_GAMMA_EXPONENT
#define SK_GAMMA_EXPONENT (2.2f)
#endif
#ifdef SK_GAMMA_SRGB
#undef SK_GAMMA_EXPONENT
#define SK_GAMMA_EXPONENT (0.0f)
#endif
//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import.
#include "SkFontLCDConfig.h"

View File

@ -15,7 +15,6 @@
#include "SkPaint.h"
class SkBitmap;
class SkBounder;
class SkClipStack;
class SkBaseDevice;
class SkMatrix;
@ -140,7 +139,6 @@ public:
const SkClipStack* fClipStack; // optional
SkBaseDevice* fDevice; // optional
SkBounder* fBounder; // optional
SkDrawProcs* fProcs; // optional
#ifdef SK_DEBUG

View File

@ -10,7 +10,10 @@
#ifndef SkDrawLooper_DEFINED
#define SkDrawLooper_DEFINED
#include "SkBlurTypes.h"
#include "SkFlattenable.h"
#include "SkPoint.h"
#include "SkColor.h"
class SkCanvas;
class SkPaint;
@ -35,7 +38,7 @@ public:
* Subclasses of SkDrawLooper should create a subclass of this object to
* hold state specific to their subclass.
*/
class SK_API Context : public SkNoncopyable {
class SK_API Context : ::SkNoncopyable {
public:
Context() {}
virtual ~Context() {}
@ -88,6 +91,24 @@ public:
virtual void computeFastBounds(const SkPaint& paint,
const SkRect& src, SkRect* dst) const;
struct BlurShadowRec {
SkScalar fSigma;
SkVector fOffset;
SkColor fColor;
SkBlurStyle fStyle;
SkBlurQuality fQuality;
};
/**
* If this looper can be interpreted as having two layers, such that
* 1. The first layer (bottom most) just has a blur and translate
* 2. The second layer has no modifications to either paint or canvas
* 3. No other layers.
* then return true, and if not null, fill out the BlurShadowRec).
*
* If any of the above are not met, return false and ignore the BlurShadowRec parameter.
*/
virtual bool asABlurShadow(BlurShadowRec*) const;
SK_TO_STRING_PUREVIRT()
SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper)

View File

@ -0,0 +1,29 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkDrawPictureCallback_DEFINED
#define SkDrawPictureCallback_DEFINED
/**
* Subclasses of this can be passed to canvas.drawPicture(). During the drawing
* of the picture, this callback will periodically be invoked. If its
* abortDrawing() returns true, then picture playback will be interrupted.
*
* The resulting drawing is undefined, as there is no guarantee how often the
* callback will be invoked. If the abort happens inside some level of nested
* calls to save(), restore will automatically be called to return the state
* to the same level it was before the drawPicture call was made.
*/
class SK_API SkDrawPictureCallback {
public:
SkDrawPictureCallback() {}
virtual ~SkDrawPictureCallback() {}
virtual bool abortDrawing() = 0;
};
#endif//SkDrawPictureCallback_DEFINED

View File

@ -12,13 +12,16 @@
// namely thread sanitizer. This is a cut-down version of the full dynamic_annotations library with
// only the features used by Skia.
// We check the same define to know to enable the annotations, but prefix all our macros with SK_.
#if DYNAMIC_ANNOTATIONS_ENABLED
#if SK_DYNAMIC_ANNOTATIONS_ENABLED
extern "C" {
// TSAN provides these hooks.
void AnnotateIgnoreReadsBegin(const char* file, int line);
void AnnotateIgnoreReadsEnd(const char* file, int line);
void AnnotateIgnoreWritesBegin(const char* file, int line);
void AnnotateIgnoreWritesEnd(const char* file, int line);
void AnnotateBenignRaceSized(const char* file, int line,
const volatile void* addr, long size, const char* desc);
} // extern "C"
// SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to
@ -37,10 +40,74 @@ inline T SK_ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
return read;
}
#else // !DYNAMIC_ANNOTATIONS_ENABLED
// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes.
template <typename T>
inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const volatile T& val) {
AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
*ptr = val;
AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
}
// Ignore racy reads and racy writes to this pointer, indefinitely.
// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ.
template <typename T>
void SK_ANNOTATE_BENIGN_RACE(T* ptr) {
AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE");
}
#else // !SK_DYNAMIC_ANNOTATIONS_ENABLED
#define SK_ANNOTATE_UNPROTECTED_READ(x) (x)
#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val)
#define SK_ANNOTATE_BENIGN_RACE(ptr)
#endif
// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g.
// - SkMatrix type mask
// - SkPixelRef genIDs
template <typename T>
class SkTRacy {
public:
operator const T() const {
return SK_ANNOTATE_UNPROTECTED_READ(fVal);
}
SkTRacy& operator=(const T& val) {
SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val);
return *this;
}
private:
T fVal;
};
// This is like SkTRacy, but allows you to return the value by reference.
// TSAN is better at suppressing SkTRacy than SkTRacyReffable, so use SkTRacy when possible.
//
// We use this for SkPathRef bounds, which is an SkRect we pass around by reference publically.
template <typename T>
class SkTRacyReffable {
public:
SkTRacyReffable() { SK_ANNOTATE_BENIGN_RACE(&fVal); }
operator const T&() const {
return fVal;
}
SkTRacyReffable& operator=(const T& val) {
fVal = val;
return *this;
}
const T* get() const { return &fVal; }
T* get() { return &fVal; }
const T* operator->() const { return &fVal; }
T* operator->() { return &fVal; }
private:
T fVal;
};
#endif//SkDynamicAnnotations_DEFINED

View File

@ -1,43 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkEmptyShader_DEFINED
#define SkEmptyShader_DEFINED
#include "SkShader.h"
/**
* \class SkEmptyShader
* 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() {}
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;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
protected:
SkEmptyShader(SkReadBuffer& buffer) : INHERITED(buffer) {}
private:
typedef SkShader INHERITED;
};
#endif

View File

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkEndian_DEFINED
#define SkEndian_DEFINED
@ -29,10 +27,10 @@
/** Swap the two bytes in the low 16bits of the parameters.
e.g. 0x1234 -> 0x3412
*/
static inline uint16_t SkEndianSwap16(U16CPU value) {
SkASSERT(value == (uint16_t)value);
static inline uint16_t SkEndianSwap16(uint16_t value) {
return static_cast<uint16_t>((value >> 8) | (value << 8));
}
template<uint16_t N> struct SkTEndianSwap16 {
static const uint16_t value = static_cast<uint16_t>((N >> 8) | ((N & 0xFF) << 8));
};
@ -53,11 +51,12 @@ static inline void SkEndianSwap16s(uint16_t array[], int count) {
e.g. 0x12345678 -> 0x78563412
*/
static inline uint32_t SkEndianSwap32(uint32_t value) {
return ((value & 0xFF) << 24) |
((value & 0xFF00) << 8) |
((value & 0xFF0000) >> 8) |
return ((value & 0xFF) << 24) |
((value & 0xFF00) << 8) |
((value & 0xFF0000) >> 8) |
(value >> 24);
}
template<uint32_t N> struct SkTEndianSwap32 {
static const uint32_t value = ((N & 0xFF) << 24) |
((N & 0xFF00) << 8) |

View File

@ -105,11 +105,12 @@ static inline SkFixed SkFixedCos(SkFixed radians) {
#define SkFixedMul(a,b) SkFixedMul_longlong(a,b)
#endif
#if defined(SK_CPU_ARM)
#if defined(SK_CPU_ARM32)
/* This guy does not handle NaN or other obscurities, but is faster than
than (int)(x*65536)
than (int)(x*65536). When built on Android with -Os, needs forcing
to inline or we lose the speed benefit.
*/
inline SkFixed SkFloatToFixed_arm(float x)
SK_ALWAYS_INLINE SkFixed SkFloatToFixed_arm(float x)
{
int32_t y, z;
asm("movs %1, %3, lsl #1 \n"

View File

@ -61,7 +61,7 @@ public:
kSkPixelRef_Type,
kSkRasterizer_Type,
kSkShader_Type,
kSkUnitMapper_Type,
kSkUnused_Type, // used to be SkUnitMapper
kSkXfermode_Type,
};

View File

@ -14,6 +14,12 @@
#include <math.h>
#include <float.h>
// For _POSIX_VERSION
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
#include <unistd.h>
#endif
#include "SkFloatBits.h"
// C++98 cmath std::pow seems to be the earliest portable way to get float pow.
@ -24,9 +30,24 @@ static inline float sk_float_pow(float base, float exp) {
}
static inline float sk_float_copysign(float x, float y) {
// c++11 contains a 'float copysign(float, float)' function in <cmath>.
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
return copysign(x, y);
// Posix has demanded 'float copysignf(float, float)' (from C99) since Issue 6.
#elif defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
return copysignf(x, y);
// Visual studio prior to 13 only has 'double _copysign(double, double)'.
#elif defined(_MSC_VER)
return (float)_copysign(x, y);
// Otherwise convert to bits and extract sign.
#else
int32_t xbits = SkFloat2Bits(x);
int32_t ybits = SkFloat2Bits(y);
return SkBits2Float((xbits & 0x7FFFFFFF) | (ybits & 0x80000000));
#endif
}
#ifdef SK_BUILD_FOR_WINCE

View File

@ -0,0 +1,161 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkFont_DEFINED
#define SkFont_DEFINED
#include "SkRefCnt.h"
#include "SkScalar.h"
class SkPaint;
class SkTypeface;
enum SkTextEncoding {
kUTF8_SkTextEncoding,
kUTF16_SkTextEncoding,
kUTF32_SkTextEncoding,
kGlyphID_SkTextEncoding,
};
/*
1. The Hinting enum in SkPaint is gone entirely, absorbed into SkFont's flags.
2. SkPaint Flags look like this today
enum Flags {
kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
kDither_Flag = 0x04, //!< mask to enable dithering
kUnderlineText_Flag = 0x08, //!< mask to enable underline text
kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
kLinearText_Flag = 0x40, //!< mask to enable linear-text
kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
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
kVerticalText_Flag = 0x1000,
kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
};
SkFont would absorb these:
kFakeBoldText_Flag = 0x20, //!< mask to enable fake-bold text
kLinearText_Flag = 0x40, //!< mask to enable linear-text
kSubpixelText_Flag = 0x80, //!< mask to enable subpixel text positioning
kDevKernText_Flag = 0x100, //!< mask to enable device kerning text
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
kVerticalText_Flag = 0x1000,
kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it
leaving these still in paint
kAntiAlias_Flag = 0x01, //!< mask to enable antialiasing
kDither_Flag = 0x04, //!< mask to enable dithering
kUnderlineText_Flag = 0x08, //!< mask to enable underline text
kStrikeThruText_Flag = 0x10, //!< mask to enable strike-thru text
3. Antialiasing
SkFont has a mask-type: BW, AA, LCD
SkPaint has antialias boolean
What to do if the font's mask-type disagrees with the paint?
*/
class SkFont : public SkRefCnt {
public:
enum Flags {
/**
* Use the system's automatic hinting mechanism to hint the typeface.
* If both bytecode and auto hints are specified, attempt to use the bytecodes first.
* If that fails (e.g. there are no codes), then attempt to autohint.
*/
kEnableAutoHints_Flag = 1 << 0,
/**
* If the typeface contains explicit bytecodes for hinting, use them.
* If both bytecode and auto hints are specified, attempt to use the bytecodes first;
* if that fails (e.g. there are no codes), then attempt to autohint.
*/
kEnableByteCodeHints_Flag = 1 << 1,
/**
* Use rounded metric values (e.g. advance).
* If either auto or bytecode hinting was used, apply those results to the metrics of the
* glyphs as well. If no hinting was applied, the metrics will just be rounded to the
* nearest integer.
*
* This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs
* (see SkCanvas drawText and drawPosText).
*/
kUseNonlinearMetrics_Flag = 1 << 2,
kVertical_Flag = 1 << 3,
kEmbeddedBitmaps_Flag = 1 << 4,
kGenA8FromLCD_Flag = 1 << 5,
kEmbolden_Flag = 1 << 6,
kDevKern_Flag = 1 << 7, // ifdef ANDROID ?
};
enum MaskType {
kBW_MaskType,
kA8_MaskType,
kLCD_MaskType,
};
static SkFont* Create(SkTypeface*, SkScalar size, MaskType, uint32_t flags);
static SkFont* Create(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX,
MaskType, uint32_t flags);
/**
* Return a font with the same attributes of this font, but with the specified size.
* If size is not supported (e.g. <= 0 or non-finite) NULL will be returned.
*/
SkFont* cloneWithSize(SkScalar size) const;
SkTypeface* getTypeface() const { return fTypeface; }
SkScalar getSize() const { return fSize; }
SkScalar getScaleX() const { return fScaleX; }
SkScalar getSkewX() const { return fSkewX; }
uint32_t getFlags() const { return fFlags; }
MaskType getMaskType() const { return (MaskType)fMaskType; }
bool isVertical() const { return SkToBool(fFlags & kVertical_Flag); }
bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_Flag); }
bool isEnableAutoHints() const { return SkToBool(fFlags & kEnableAutoHints_Flag); }
bool isEnableByteCodeHints() const { return SkToBool(fFlags & kEnableByteCodeHints_Flag); }
bool isUseNonLinearMetrics() const { return SkToBool(fFlags & kUseNonlinearMetrics_Flag); }
int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding,
uint16_t glyphs[], int maxGlyphCount) const;
SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding) const;
static SkFont* Testing_CreateFromPaint(const SkPaint&);
private:
enum {
kAllFlags = 0xFF,
};
SkFont(SkTypeface*, SkScalar size, SkScalar scaleX, SkScalar skewX, MaskType, uint32_t flags);
virtual ~SkFont();
SkTypeface* fTypeface;
SkScalar fSize;
SkScalar fScaleX;
SkScalar fSkewX;
uint16_t fFlags;
uint8_t fMaskType;
// uint8_t fPad;
};
#endif

View File

@ -79,9 +79,47 @@ public:
*/
static void PurgeFontCache();
static size_t GetImageCacheBytesUsed();
static size_t GetImageCacheByteLimit();
static size_t SetImageCacheByteLimit(size_t newLimit);
/**
* Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is
* expensive, so the result is saved in the global Scaled Image
* Cache.
*
* This function returns the memory usage of the Scaled Image Cache.
*/
static size_t GetImageCacheTotalBytesUsed();
/**
* These functions get/set the memory usage limit for the Scaled
* Image Cache. Bitmaps are purged from the cache when the
* memory useage exceeds this limit.
*/
static size_t GetImageCacheTotalByteLimit();
static size_t SetImageCacheTotalByteLimit(size_t newLimit);
// DEPRECATED
static size_t GetImageCacheBytesUsed() {
return GetImageCacheTotalBytesUsed();
}
// DEPRECATED
static size_t GetImageCacheByteLimit() {
return GetImageCacheTotalByteLimit();
}
// DEPRECATED
static size_t SetImageCacheByteLimit(size_t newLimit) {
return SetImageCacheTotalByteLimit(newLimit);
}
/**
* Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is
* expensive, so the result is saved in the global Scaled Image
* Cache. When the resulting bitmap is too large, this can
* overload the cache. If the ImageCacheSingleAllocationByteLimit
* is set to a non-zero number, and the resulting bitmap would be
* larger than that value, the bitmap scaling algorithm falls
* back onto a cheaper algorithm and does not cache the result.
* Zero is the default value.
*/
static size_t GetImageCacheSingleAllocationByteLimit();
static size_t SetImageCacheSingleAllocationByteLimit(size_t newLimit);
/**
* Applications with command line options may pass optional state, such

View File

@ -12,17 +12,14 @@
#include "SkImageEncoder.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkShader.h"
class SkData;
class SkCanvas;
class SkPaint;
class SkShader;
class GrContext;
class GrTexture;
// need for TileMode
#include "SkShader.h"
/**
* SkImage is an abstraction for drawing a rectagle of pixels, though the
* particular type of image could be actually storing its data on the GPU, or
@ -61,8 +58,9 @@ public:
*/
GrTexture* getTexture();
SkShader* newShaderClamp() const;
SkShader* newShader(SkShader::TileMode, SkShader::TileMode) const;
virtual SkShader* newShader(SkShader::TileMode,
SkShader::TileMode,
const SkMatrix* localMatrix = NULL) const;
void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*);

View File

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkImageDecoder_DEFINED
#define SkImageDecoder_DEFINED
@ -24,7 +22,7 @@ class SkStreamRewindable;
Base class for decoding compressed images into a SkBitmap
*/
class SkImageDecoder : public SkNoncopyable {
class SkImageDecoder : SkNoncopyable {
public:
virtual ~SkImageDecoder();
@ -37,8 +35,10 @@ public:
kPNG_Format,
kWBMP_Format,
kWEBP_Format,
kPKM_Format,
kKTX_Format,
kLastKnownFormat = kWEBP_Format,
kLastKnownFormat = kKTX_Format,
};
/** Return the format of image this decoder can decode. If this decoder can decode multiple
@ -135,6 +135,7 @@ public:
Peeker* getPeeker() const { return fPeeker; }
Peeker* setPeeker(Peeker*);
#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
/** \class Chooser
Base class for optional callbacks to choose an image from a format that
@ -156,7 +157,9 @@ public:
Chooser* getChooser() const { return fChooser; }
Chooser* setChooser(Chooser*);
#endif
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
/**
* Optional table describing the caller's preferred config based on
* information about the src data. Each field should be set to the
@ -200,6 +203,21 @@ public:
* was previously set.
*/
void resetPrefConfigTable() { fUsePrefTable = false; }
#endif
/**
* By default, the codec will try to comply with the "pref" colortype
* that is passed to decode() or decodeSubset(). However, this can be called
* to override that, causing the codec to try to match the src depth instead
* (as shown below).
*
* src_8Index -> kIndex_8_SkColorType
* src_8Gray -> kN32_SkColorType
* src_8bpc -> kN32_SkColorType
*/
void setPreserveSrcDepth(bool preserve) {
fPreserveSrcDepth = preserve;
}
SkBitmap::Allocator* getAllocator() const { return fAllocator; }
SkBitmap::Allocator* setAllocator(SkBitmap::Allocator*);
@ -235,22 +253,22 @@ public:
}
/** Passed to the decode method. If kDecodeBounds_Mode is passed, then
only the bitmap's width/height/config need be set. If kDecodePixels_Mode
only the bitmap's info need be set. If kDecodePixels_Mode
is passed, then the bitmap must have pixels or a pixelRef.
*/
enum Mode {
kDecodeBounds_Mode, //!< only return width/height/config in bitmap
kDecodeBounds_Mode, //!< only return info in bitmap
kDecodePixels_Mode //!< return entire bitmap (including pixels)
};
/** Given a stream, decode it into the specified bitmap.
If the decoder can decompress the image, it calls bitmap.setConfig(),
If the decoder can decompress the image, it calls bitmap.setInfo(),
and then if the Mode is kDecodePixels_Mode, call allocPixelRef(),
which will allocated a pixelRef. To access the pixel memory, the codec
needs to call lockPixels/unlockPixels on the
bitmap. It can then set the pixels with the decompressed image.
* If the image cannot be decompressed, return false. After the
* decoding, the function converts the decoded config in bitmap
* decoding, the function converts the decoded colortype in bitmap
* to pref if possible. Whether a conversion is feasible is
* tested by Bitmap::canCopyTo(pref).
@ -261,13 +279,10 @@ public:
If a Peeker is installed via setPeeker, it may be used to peek into
meta data during the decode.
If a Chooser is installed via setChooser, it may be used to select
which image to return from a format that contains multiple images.
*/
bool decode(SkStream*, SkBitmap* bitmap, SkBitmap::Config pref, Mode);
bool decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode);
bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) {
return this->decode(stream, bitmap, SkBitmap::kNo_Config, mode);
return this->decode(stream, bitmap, kUnknown_SkColorType, mode);
}
/**
@ -286,12 +301,7 @@ public:
* Return true for success.
* Return false if the index is never built or failing in decoding.
*/
bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkBitmap::Config pref);
SK_ATTR_DEPRECATED("use decodeSubset() instead")
bool decodeRegion(SkBitmap* bitmap, const SkIRect& rect, SkBitmap::Config pref) {
return this->decodeSubset(bitmap, rect, pref);
}
bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkColorType pref);
/** Given a stream, this will try to find an appropriate decoder object.
If none is found, the method returns NULL.
@ -301,34 +311,31 @@ public:
/** Decode the image stored in the specified file, and store the result
in bitmap. Return true for success or false on failure.
@param prefConfig If the PrefConfigTable is not set, prefer this config.
@param pref If the PrefConfigTable is not set, prefer this colortype.
See NOTE ABOUT PREFERRED CONFIGS.
@param format On success, if format is non-null, it is set to the format
of the decoded file. On failure it is ignored.
*/
static bool DecodeFile(const char file[], SkBitmap* bitmap,
SkBitmap::Config prefConfig, Mode,
static bool DecodeFile(const char file[], SkBitmap* bitmap, SkColorType pref, Mode,
Format* format = NULL);
static bool DecodeFile(const char file[], SkBitmap* bitmap) {
return DecodeFile(file, bitmap, SkBitmap::kNo_Config,
kDecodePixels_Mode, NULL);
return DecodeFile(file, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
}
/** Decode the image stored in the specified memory buffer, and store the
result in bitmap. Return true for success or false on failure.
@param prefConfig If the PrefConfigTable is not set, prefer this config.
@param pref If the PrefConfigTable is not set, prefer this colortype.
See NOTE ABOUT PREFERRED CONFIGS.
@param format On success, if format is non-null, it is set to the format
of the decoded buffer. On failure it is ignored.
*/
static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap,
SkBitmap::Config prefConfig, Mode,
Format* format = NULL);
static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap, SkColorType pref,
Mode, Format* format = NULL);
static bool DecodeMemory(const void* buffer, size_t size, SkBitmap* bitmap){
return DecodeMemory(buffer, size, bitmap, SkBitmap::kNo_Config,
kDecodePixels_Mode, NULL);
return DecodeMemory(buffer, size, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
}
/**
@ -349,34 +356,18 @@ public:
/** Decode the image stored in the specified SkStreamRewindable, and store the result
in bitmap. Return true for success or false on failure.
@param prefConfig If the PrefConfigTable is not set, prefer this config.
@param pref If the PrefConfigTable is not set, prefer this colortype.
See NOTE ABOUT PREFERRED CONFIGS.
@param format On success, if format is non-null, it is set to the format
of the decoded stream. On failure it is ignored.
*/
static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap,
SkBitmap::Config prefConfig, Mode,
static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap, SkColorType pref, Mode,
Format* format = NULL);
static bool DecodeStream(SkStreamRewindable* stream, SkBitmap* bitmap) {
return DecodeStream(stream, bitmap, SkBitmap::kNo_Config,
kDecodePixels_Mode, NULL);
return DecodeStream(stream, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL);
}
/** Return the default config for the running device.
Currently this used as a suggestion to image decoders that need to guess
what config they should decode into.
Default is kNo_Config, but this can be changed with SetDeviceConfig()
*/
static SkBitmap::Config GetDeviceConfig();
/** Set the default config for the running device.
Currently this used as a suggestion to image decoders that need to guess
what config they should decode into.
Default is kNo_Config.
This can be queried with GetDeviceConfig()
*/
static void SetDeviceConfig(SkBitmap::Config);
protected:
// must be overridden in subclasses. This guy is called by decode(...)
virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0;
@ -418,12 +409,6 @@ protected:
*/
void copyFieldsToOther(SkImageDecoder* other);
/**
* Return the default preference being used by the current or latest call to
* decode.
*/
SkBitmap::Config getDefaultPref() { return fDefaultPref; }
/** Can be queried from within onDecode, to see if the user (possibly in
a different thread) has requested the decode to cancel. If this returns
true, your onDecode() should stop and return false.
@ -439,13 +424,19 @@ public:
protected:
SkImageDecoder();
/**
* Return the default preference being used by the current or latest call to decode.
*/
SkColorType getDefaultPref() { return fDefaultPref; }
#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
// helper function for decoders to handle the (common) case where there is only
// once choice available in the image file.
bool chooseFromOneChoice(SkBitmap::Config config, int width, int height) const;
bool chooseFromOneChoice(SkColorType, int width, int height) const;
#endif
/* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's
width/height/rowbytes/config. Returns true on success. This method handles checking
for an optional Allocator.
/* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's info.
Returns true on success. This method handles checking for an optional Allocator.
*/
bool allocPixelRef(SkBitmap*, SkColorTable*) const;
@ -460,25 +451,27 @@ protected:
// 8 bits per component. Used for 24 bit if there is no alpha.
k32Bit_SrcDepth,
};
/** The subclass, inside onDecode(), calls this to determine the config of
/** The subclass, inside onDecode(), calls this to determine the colorType of
the returned bitmap. SrcDepth and hasAlpha reflect the raw data of the
src image. This routine returns the caller's preference given
srcDepth and hasAlpha, or kNo_Config if there is no preference.
Note: this also takes into account GetDeviceConfig(), so the subclass
need not call that.
srcDepth and hasAlpha, or kUnknown_SkColorType if there is no preference.
*/
SkBitmap::Config getPrefConfig(SrcDepth, bool hasAlpha) const;
SkColorType getPrefColorType(SrcDepth, bool hasAlpha) const;
private:
Peeker* fPeeker;
#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
Chooser* fChooser;
#endif
SkBitmap::Allocator* fAllocator;
int fSampleSize;
SkBitmap::Config fDefaultPref; // use if fUsePrefTable is false
SkColorType fDefaultPref; // use if fUsePrefTable is false
#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG
PrefConfigTable fPrefTable; // use if fUsePrefTable is true
bool fDitherImage;
bool fUsePrefTable;
#endif
bool fPreserveSrcDepth;
bool fDitherImage;
bool fSkipWritingZeroes;
mutable bool fShouldCancelDecode;
bool fPreferQualityOverSpeed;
@ -530,7 +523,8 @@ DECLARE_DECODER_CREATOR(JPEGImageDecoder);
DECLARE_DECODER_CREATOR(PNGImageDecoder);
DECLARE_DECODER_CREATOR(WBMPImageDecoder);
DECLARE_DECODER_CREATOR(WEBPImageDecoder);
DECLARE_DECODER_CREATOR(PKMImageDecoder);
DECLARE_DECODER_CREATOR(KTXImageDecoder);
// Typedefs to make registering decoder and formatter callbacks easier.
// These have to be defined outside SkImageDecoder. :(

View File

@ -26,6 +26,7 @@ public:
kPNG_Type,
kWBMP_Type,
kWEBP_Type,
kKTX_Type,
};
static SkImageEncoder* Create(Type);
@ -96,8 +97,13 @@ protected:
DECLARE_ENCODER_CREATOR(ARGBImageEncoder);
DECLARE_ENCODER_CREATOR(JPEGImageEncoder);
DECLARE_ENCODER_CREATOR(PNGImageEncoder);
DECLARE_ENCODER_CREATOR(KTXImageEncoder);
DECLARE_ENCODER_CREATOR(WEBPImageEncoder);
#ifdef SK_BUILD_FOR_IOS
DECLARE_ENCODER_CREATOR(PNGImageEncoder_IOS);
#endif
// Typedef to make registering encoder callback easier
// This has to be defined outside SkImageEncoder. :(
typedef SkTRegistry<SkImageEncoder*(*)(SkImageEncoder::Type)> SkImageEncoder_EncodeReg;

View File

@ -11,13 +11,13 @@
#include "SkFlattenable.h"
#include "SkMatrix.h"
#include "SkRect.h"
#include "SkTemplates.h"
class SkBitmap;
class SkColorFilter;
class SkBaseDevice;
struct SkIPoint;
class SkShader;
class GrEffectRef;
class GrEffect;
class GrTexture;
/**
@ -49,16 +49,30 @@ public:
uint32_t fFlags;
};
class SK_API Cache : public SkRefCnt {
public:
// By default, we cache only image filters with 2 or more children.
// Values less than 2 mean always cache; values greater than 2 are not supported.
static Cache* Create(int minChildren = 2);
virtual ~Cache() {}
virtual bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) = 0;
virtual void set(const SkImageFilter* key,
const SkBitmap& result, const SkIPoint& offset) = 0;
virtual void remove(const SkImageFilter* key) = 0;
};
class Context {
public:
Context(const SkMatrix& ctm, const SkIRect& clipBounds) :
fCTM(ctm), fClipBounds(clipBounds) {
Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) :
fCTM(ctm), fClipBounds(clipBounds), fCache(cache) {
}
const SkMatrix& ctm() const { return fCTM; }
const SkIRect& clipBounds() const { return fClipBounds; }
Cache* cache() const { return fCache; }
private:
SkMatrix fCTM;
SkIRect fClipBounds;
Cache* fCache;
};
class Proxy {
@ -172,17 +186,47 @@ public:
SkBitmap* result, SkIPoint* offset) const;
#endif
/**
* Set an external cache to be used for all image filter processing. This
* will replace the default intra-frame cache.
*/
static void SetExternalCache(Cache* cache);
/**
* Returns the currently-set external cache, or NULL if none is set.
*/
static Cache* GetExternalCache();
SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
protected:
class Common {
public:
Common() {}
~Common();
bool unflatten(SkReadBuffer&, int expectedInputs = -1);
CropRect cropRect() const { return fCropRect; }
int inputCount() const { return fInputs.count(); }
SkImageFilter** inputs() const { return fInputs.get(); }
// If the caller wants a copy of the inputs, call this and it will transfer ownership
// of the unflattened input filters to the caller. This is just a short-cut for copying
// the inputs, calling ref() on each, and then waiting for Common's destructor to call
// unref() on each.
void detachInputs(SkImageFilter** inputs);
private:
CropRect fCropRect;
// most filters accept at most 2 input-filters
SkAutoSTArray<2, SkImageFilter*> fInputs;
void allocInputs(int count);
};
SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect = NULL);
// Convenience constructor for 1-input filters.
explicit SkImageFilter(SkImageFilter* input, const CropRect* cropRect = NULL);
// Convenience constructor for 2-input filters.
SkImageFilter(SkImageFilter* input1, SkImageFilter* input2, const CropRect* cropRect = NULL);
virtual ~SkImageFilter();
/**
@ -258,12 +302,11 @@ protected:
* will be called with (NULL, NULL, SkMatrix::I()) to query for support,
* so returning "true" indicates support for all possible matrices.
*/
virtual bool asNewEffect(GrEffectRef** effect,
virtual bool asNewEffect(GrEffect** effect,
GrTexture*,
const SkMatrix& matrix,
const SkIRect& bounds) const;
private:
typedef SkFlattenable INHERITED;
int fInputCount;

View File

@ -8,8 +8,8 @@
#ifndef SkImageGenerator_DEFINED
#define SkImageGenerator_DEFINED
#include "SkDiscardableMemory.h"
#include "SkImageInfo.h"
#include "SkColor.h"
class SkBitmap;
class SkData;
@ -31,15 +31,15 @@ class SkImageGenerator;
* @param destination Upon success, this bitmap will be
* configured and have a pixelref installed.
*
* @param factory If not NULL, this object will be used as a
* source of discardable memory when decoding. If NULL, then
* SkDiscardableMemory::Create() will be called.
*
* @return true iff successful.
*/
SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator* generator,
SkBitmap* destination,
SkDiscardableMemory::Factory* factory = NULL);
SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination);
/**
* Purges all unlocked discardable memory in Skia's global
* discardable memory pool.
*/
SK_API void SkPurgeGlobalDiscardableMemoryPool();
/**
@ -54,6 +54,13 @@ public:
*/
virtual ~SkImageGenerator() { }
#ifdef SK_SUPPORT_LEGACY_IMAGEGENERATORAPI
virtual SkData* refEncodedData() { return this->onRefEncodedData(); }
virtual bool getInfo(SkImageInfo* info) { return this->onGetInfo(info); }
virtual bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) {
return this->onGetPixels(info, pixels, rowBytes, NULL, NULL);
}
#else
/**
* Return a ref to the encoded (i.e. compressed) representation,
* of this data.
@ -61,7 +68,7 @@ public:
* If non-NULL is returned, the caller is responsible for calling
* unref() on the data when it is finished.
*/
virtual SkData* refEncodedData() { return NULL; }
SkData* refEncodedData() { return this->onRefEncodedData(); }
/**
* Return some information about the image, allowing the owner of
@ -72,7 +79,7 @@ public:
*
* @return false if anything goes wrong.
*/
virtual bool getInfo(SkImageInfo* info) = 0;
bool getInfo(SkImageInfo* info);
/**
* Decode into the given pixels, a block of memory of size at
@ -90,12 +97,45 @@ public:
* different output-configs, which the implementation can
* decide to support or not.
*
* If info is kIndex8_SkColorType, then the caller must provide storage for up to 256
* SkPMColor values in ctable. On success the generator must copy N colors into that storage,
* (where N is the logical number of table entries) and set ctableCount to N.
*
* If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount
* is not null, it will be set to 0.
*
* @return false if anything goes wrong or if the image info is
* unsupported.
*/
virtual bool getPixels(const SkImageInfo& info,
void* pixels,
size_t rowBytes) = 0;
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
SkPMColor ctable[], int* ctableCount);
/**
* Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType.
*/
bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
#endif
/**
* If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes
* is 0, this imagegenerator should output the sizes and return true if it can efficiently
* return YUV planar data. If it cannot, it should return false. Note that either planes and
* rowBytes are both fully defined and non NULL/non 0 or they are both NULL or have NULL or 0
* entries only. Having only partial planes/rowBytes information is not supported.
*
* If all planes and rowBytes entries are non NULL or non 0, then it should copy the
* associated YUV data into those planes of memory supplied by the caller. It should validate
* that the sizes match what it expected. If the sizes do not match, it should return false.
*/
bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
protected:
virtual SkData* onRefEncodedData();
virtual bool onGetInfo(SkImageInfo* info);
virtual bool onGetPixels(const SkImageInfo& info,
void* pixels, size_t rowBytes,
SkPMColor ctable[], int* ctableCount);
virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
};
#endif // SkImageGenerator_DEFINED

View File

@ -67,6 +67,10 @@ static inline bool SkAlphaTypeIsValid(unsigned value) {
/**
* Describes how to interpret the components of a pixel.
*
* kN32_SkColorType is an alias for whichever 32bit ARGB format is the "native"
* form for skia's blitters. Use this if you don't have a swizzle preference
* for 32bit pixels.
*/
enum SkColorType {
kUnknown_SkColorType,
@ -80,12 +84,16 @@ enum SkColorType {
kLastEnum_SkColorType = kIndex_8_SkColorType,
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
kPMColor_SkColorType = kBGRA_8888_SkColorType
kN32_SkColorType = kBGRA_8888_SkColorType,
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
kPMColor_SkColorType = kRGBA_8888_SkColorType
kN32_SkColorType = kRGBA_8888_SkColorType,
#else
#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
#endif
#ifdef SK_SUPPORT_LEGACY_N32_NAME
kPMColor_SkColorType = kN32_SkColorType
#endif
};
static int SkColorTypeBytesPerPixel(SkColorType ct) {
@ -115,6 +123,15 @@ static inline bool SkColorTypeIsValid(unsigned value) {
///////////////////////////////////////////////////////////////////////////////
/**
* Return true if alphaType is supported by colorType. If there is a canonical
* alphaType for this colorType, return it in canonical.
*/
bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
SkAlphaType* canonical = NULL);
///////////////////////////////////////////////////////////////////////////////
/**
* Describe an image's dimensions and pixel type.
*/
@ -136,7 +153,7 @@ struct SkImageInfo {
*/
static SkImageInfo MakeN32(int width, int height, SkAlphaType at) {
SkImageInfo info = {
width, height, kPMColor_SkColorType, at
width, height, kN32_SkColorType, at
};
return info;
}
@ -146,7 +163,7 @@ struct SkImageInfo {
*/
static SkImageInfo MakeN32Premul(int width, int height) {
SkImageInfo info = {
width, height, kPMColor_SkColorType, kPremul_SkAlphaType
width, height, kN32_SkColorType, kPremul_SkAlphaType
};
return info;
}
@ -172,6 +189,13 @@ struct SkImageInfo {
return info;
}
static SkImageInfo MakeUnknown() {
SkImageInfo info = {
0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType
};
return info;
}
int width() const { return fWidth; }
int height() const { return fHeight; }
SkColorType colorType() const { return fColorType; }
@ -185,6 +209,14 @@ struct SkImageInfo {
SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); }
/**
* Return a new ImageInfo with the same colortype and alphatype as this info,
* but with the specified width and height.
*/
SkImageInfo makeWH(int newWidth, int newHeight) const {
return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType);
}
int bytesPerPixel() const {
return SkColorTypeBytesPerPixel(fColorType);
}

View File

@ -47,11 +47,11 @@ extern bool gPrintInstCount;
public: \
SkInstanceCountHelper() { \
SK_DECLARE_STATIC_ONCE(once); \
SkOnce(&once, init, 0); \
SkOnce(&once, init); \
sk_atomic_inc(GetInstanceCountPtr()); \
} \
\
static void init(int) { \
static void init() { \
initStep \
} \
\
@ -73,9 +73,14 @@ extern bool gPrintInstCount;
return gChildren; \
} \
\
static void create_mutex(SkMutex** mutex) { \
*mutex = SkNEW(SkMutex); \
} \
static SkBaseMutex& GetChildrenMutex() { \
SK_DECLARE_STATIC_MUTEX(childrenMutex); \
return childrenMutex; \
static SkMutex* childrenMutex; \
SK_DECLARE_STATIC_ONCE(once); \
SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\
return *childrenMutex; \
} \
\
} fInstanceCountHelper; \

View File

@ -64,9 +64,6 @@ public:
* The SkData will be ref()ed and on destruction of the PielRef,
* the SkData will be unref()ed.
*
* @param offset (in bytes) into the provided SkData that the
* first pixel is located at.
*
* This pixelref will ref() the specified colortable (if not NULL).
*
* Returns NULL on failure.
@ -74,29 +71,25 @@ public:
static SkMallocPixelRef* NewWithData(const SkImageInfo& info,
size_t rowBytes,
SkColorTable* ctable,
SkData* data,
size_t offset = 0);
SkData* data);
void* getAddr() const { return fStorage; }
class PRFactory : public SkPixelRefFactory {
public:
virtual SkPixelRef* create(const SkImageInfo&,
size_t rowBytes,
SkColorTable*) SK_OVERRIDE;
};
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMallocPixelRef)
protected:
// The ownPixels version of this constructor is deprecated.
SkMallocPixelRef(const SkImageInfo&, void* addr, size_t rb, SkColorTable*,
bool ownPixels);
SkMallocPixelRef(SkReadBuffer& buffer);
virtual ~SkMallocPixelRef();
virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE;
virtual void onUnlockPixels() SK_OVERRIDE;
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE;
private:

View File

@ -10,6 +10,7 @@
#ifndef SkMaskFilter_DEFINED
#define SkMaskFilter_DEFINED
#include "SkBlurTypes.h"
#include "SkFlattenable.h"
#include "SkMask.h"
#include "SkPaint.h"
@ -18,7 +19,6 @@ class GrContext;
class GrPaint;
class SkBitmap;
class SkBlitter;
class SkBounder;
class SkMatrix;
class SkPath;
class SkRasterClip;
@ -72,7 +72,7 @@ public:
* If effect is non-NULL, a new GrEffect instance is stored in it. The caller assumes ownership
* of the effect and must unref it.
*/
virtual bool asNewEffect(GrEffectRef** effect,
virtual bool asNewEffect(GrEffect** effect,
GrTexture*,
const SkMatrix& ctm) const;
@ -138,6 +138,18 @@ public:
*/
virtual void computeFastBounds(const SkRect& src, SkRect* dest) const;
struct BlurRec {
SkScalar fSigma;
SkBlurStyle fStyle;
SkBlurQuality fQuality;
};
/**
* If this filter can be represented by a BlurRec, return true and (if not null) fill in the
* provided BlurRec parameter. If this effect cannot be represented as a BlurRec, return false
* and ignore the BlurRec parameter.
*/
virtual bool asABlur(BlurRec*) const;
SK_TO_STRING_PUREVIRT()
SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter)
@ -192,17 +204,15 @@ private:
to render that mask. Returns false if filterMask() returned false.
This method is not exported to java.
*/
bool filterPath(const SkPath& devPath, const SkMatrix& devMatrix,
const SkRasterClip&, SkBounder*, SkBlitter* blitter,
SkPaint::Style style) const;
bool filterPath(const SkPath& devPath, const SkMatrix& ctm, const SkRasterClip&, SkBlitter*,
SkPaint::Style) const;
/** Helper method that, given a roundRect in device space, will rasterize it into a kA8_Format
mask and then call filterMask(). If this returns true, the specified blitter will be called
to render that mask. Returns false if filterMask() returned false.
*/
bool filterRRect(const SkRRect& devRRect, const SkMatrix& devMatrix,
const SkRasterClip&, SkBounder*, SkBlitter* blitter,
SkPaint::Style style) const;
bool filterRRect(const SkRRect& devRRect, const SkMatrix& ctm, const SkRasterClip&,
SkBlitter*, SkPaint::Style style) const;
typedef SkFlattenable INHERITED;
};

View File

@ -12,29 +12,6 @@
#include "SkTypes.h"
/**
* Computes numer1 * numer2 / denom in full 64 intermediate precision.
* It is an error for denom to be 0. There is no special handling if
* the result overflows 32bits.
*/
int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom);
/**
* Computes (numer1 << shift) / denom in full 64 intermediate precision.
* It is an error for denom to be 0. There is no special handling if
* the result overflows 32bits.
*/
int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
/**
* Return the integer square root of value, with a bias of bitBias
*/
int32_t SkSqrtBits(int32_t value, int bitBias);
/** Return the integer square root of n, treated as a SkFixed (16.16)
*/
#define SkSqrt32(n) SkSqrtBits(n, 15)
// 64bit -> 32bit utilities
/**
@ -63,6 +40,34 @@ static inline int64_t sk_64_mul(int64_t a, int64_t b) {
///////////////////////////////////////////////////////////////////////////////
/**
* Computes numer1 * numer2 / denom in full 64 intermediate precision.
* It is an error for denom to be 0. There is no special handling if
* the result overflows 32bits.
*/
static inline int32_t SkMulDiv(int32_t numer1, int32_t numer2, int32_t denom) {
SkASSERT(denom);
int64_t tmp = sk_64_mul(numer1, numer2) / denom;
return sk_64_asS32(tmp);
}
/**
* Computes (numer1 << shift) / denom in full 64 intermediate precision.
* It is an error for denom to be 0. There is no special handling if
* the result overflows 32bits.
*/
int32_t SkDivBits(int32_t numer, int32_t denom, int shift);
/**
* Return the integer square root of value, with a bias of bitBias
*/
int32_t SkSqrtBits(int32_t value, int bitBias);
/** Return the integer square root of n, treated as a SkFixed (16.16)
*/
#define SkSqrt32(n) SkSqrtBits(n, 15)
//! Returns the number of leading zero bits (0...32)
int SkCLZ_portable(uint32_t);
@ -79,7 +84,7 @@ int SkCLZ_portable(uint32_t);
return 32;
}
}
#elif defined(SK_CPU_ARM) || defined(__GNUC__) || defined(__clang__)
#elif defined(SK_CPU_ARM32) || defined(__GNUC__) || defined(__clang__)
static inline int SkCLZ(uint32_t mask) {
// __builtin_clz(0) is undefined, so we have to detect that case.
return mask ? __builtin_clz(mask) : 32;
@ -204,7 +209,7 @@ static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
*/
template <typename In, typename Out>
inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
#ifdef SK_CPU_ARM
#ifdef SK_CPU_ARM32
// If we wrote this as in the else branch, GCC won't fuse the two into one
// divmod call, but rather a div call followed by a divmod. Silly! This
// version is just as fast as calling __aeabi_[u]idivmod manually, but with
@ -218,7 +223,7 @@ inline void SkTDivMod(In numer, In denom, Out* div, Out* mod) {
// On x86 this will just be a single idiv.
*div = static_cast<Out>(numer/denom);
*mod = static_cast<Out>(numer%denom);
#endif // SK_CPU_ARM
#endif
}
#endif

View File

@ -10,6 +10,7 @@
#ifndef SkMatrix_DEFINED
#define SkMatrix_DEFINED
#include "SkDynamicAnnotations.h"
#include "SkRect.h"
class SkString;
@ -218,57 +219,57 @@ public:
/** Set the matrix to skew by sx and sy.
*/
void setSkew(SkScalar kx, SkScalar ky);
/** Set the matrix to the concatenation of the two specified matrices,
returning true if the the result can be represented. Either of the
two matrices may also be the target matrix. *this = a * b;
/** Set the matrix to the concatenation of the two specified matrices.
Either of the two matrices may also be the target matrix.
*this = a * b;
*/
bool setConcat(const SkMatrix& a, const SkMatrix& b);
void setConcat(const SkMatrix& a, const SkMatrix& b);
/** Preconcats the matrix with the specified translation.
M' = M * T(dx, dy)
*/
bool preTranslate(SkScalar dx, SkScalar dy);
void preTranslate(SkScalar dx, SkScalar dy);
/** Preconcats the matrix with the specified scale.
M' = M * S(sx, sy, px, py)
*/
bool preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
void preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
/** Preconcats the matrix with the specified scale.
M' = M * S(sx, sy)
*/
bool preScale(SkScalar sx, SkScalar sy);
void preScale(SkScalar sx, SkScalar sy);
/** Preconcats the matrix with the specified rotation.
M' = M * R(degrees, px, py)
*/
bool preRotate(SkScalar degrees, SkScalar px, SkScalar py);
void preRotate(SkScalar degrees, SkScalar px, SkScalar py);
/** Preconcats the matrix with the specified rotation.
M' = M * R(degrees)
*/
bool preRotate(SkScalar degrees);
void preRotate(SkScalar degrees);
/** Preconcats the matrix with the specified skew.
M' = M * K(kx, ky, px, py)
*/
bool preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
void preSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
/** Preconcats the matrix with the specified skew.
M' = M * K(kx, ky)
*/
bool preSkew(SkScalar kx, SkScalar ky);
void preSkew(SkScalar kx, SkScalar ky);
/** Preconcats the matrix with the specified matrix.
M' = M * other
*/
bool preConcat(const SkMatrix& other);
void preConcat(const SkMatrix& other);
/** Postconcats the matrix with the specified translation.
M' = T(dx, dy) * M
*/
bool postTranslate(SkScalar dx, SkScalar dy);
void postTranslate(SkScalar dx, SkScalar dy);
/** Postconcats the matrix with the specified scale.
M' = S(sx, sy, px, py) * M
*/
bool postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
void postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py);
/** Postconcats the matrix with the specified scale.
M' = S(sx, sy) * M
*/
bool postScale(SkScalar sx, SkScalar sy);
void postScale(SkScalar sx, SkScalar sy);
/** Postconcats the matrix by dividing it by the specified integers.
M' = S(1/divx, 1/divy, 0, 0) * M
*/
@ -276,23 +277,23 @@ public:
/** Postconcats the matrix with the specified rotation.
M' = R(degrees, px, py) * M
*/
bool postRotate(SkScalar degrees, SkScalar px, SkScalar py);
void postRotate(SkScalar degrees, SkScalar px, SkScalar py);
/** Postconcats the matrix with the specified rotation.
M' = R(degrees) * M
*/
bool postRotate(SkScalar degrees);
void postRotate(SkScalar degrees);
/** Postconcats the matrix with the specified skew.
M' = K(kx, ky, px, py) * M
*/
bool postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
void postSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py);
/** Postconcats the matrix with the specified skew.
M' = K(kx, ky) * M
*/
bool postSkew(SkScalar kx, SkScalar ky);
void postSkew(SkScalar kx, SkScalar ky);
/** Postconcats the matrix with the specified matrix.
M' = other * M
*/
bool postConcat(const SkMatrix& other);
void postConcat(const SkMatrix& other);
enum ScaleToFit {
/**
@ -563,20 +564,27 @@ public:
SK_TO_STRING_NONVIRT()
/**
* Calculates the minimum stretching factor of the matrix. If the matrix has
* perspective -1 is returned.
* Calculates the minimum scaling factor of the matrix as computed from the SVD of the upper
* left 2x2. If the matrix has perspective -1 is returned.
*
* @return minumum strecthing factor
* @return minumum scale factor
*/
SkScalar getMinStretch() const;
SkScalar getMinScale() const;
/**
* Calculates the maximum stretching factor of the matrix. If the matrix has
* perspective -1 is returned.
* Calculates the maximum scaling factor of the matrix as computed from the SVD of the upper
* left 2x2. If the matrix has perspective -1 is returned.
*
* @return maximum strecthing factor
* @return maximum scale factor
*/
SkScalar getMaxStretch() const;
SkScalar getMaxScale() const;
/**
* Gets both the min and max scale factors. The min scale factor is scaleFactors[0] and the max
* is scaleFactors[1]. If the matrix has perspective false will be returned and scaleFactors
* will be unchanged.
*/
bool getMinMaxScales(SkScalar scaleFactors[2]) const;
/**
* Return a reference to a const identity matrix
@ -589,6 +597,15 @@ public:
*/
static const SkMatrix& InvalidMatrix();
/**
* Return the concatenation of two matrices, a * b.
*/
static SkMatrix Concat(const SkMatrix& a, const SkMatrix& b) {
SkMatrix result;
result.setConcat(a, b);
return result;
}
/**
* Testing routine; the matrix's type cache should never need to be
* manually invalidated during normal use.
@ -627,7 +644,7 @@ private:
};
SkScalar fMat[9];
mutable uint32_t fTypeMask;
mutable SkTRacy<uint32_t> fTypeMask;
uint8_t computeTypeMask() const;
uint8_t computePerspectiveTypeMask() const;
@ -648,7 +665,7 @@ private:
void clearTypeMask(int mask) {
// only allow a valid mask
SkASSERT((mask & kAllMasks) == mask);
fTypeMask &= ~mask;
fTypeMask = fTypeMask & ~mask;
}
TypeMask getPerspectiveTypeMaskOnly() const {

View File

@ -77,8 +77,10 @@ bool sk_fidentical(SkFILE* a, SkFILE* b);
*/
int sk_fileno(SkFILE* f);
// Returns true if something (file, directory, ???) exists at this path.
bool sk_exists(const char *path);
/** Returns true if something (file, directory, ???) exists at this path,
* and has the specified access flags.
*/
bool sk_exists(const char *path, SkFILE_Flags = (SkFILE_Flags)0);
// Returns true if a directory exists at this path.
bool sk_isdir(const char *path);
@ -118,19 +120,6 @@ public:
};
};
class SkUTF16_Str {
public:
SkUTF16_Str(const char src[]);
~SkUTF16_Str()
{
sk_free(fStr);
}
const uint16_t* get() const { return fStr; }
private:
uint16_t* fStr;
};
/**
* Functions for modifying SkStrings which represent paths on the filesystem.
*/

View File

@ -8,117 +8,71 @@
#ifndef SkOnce_DEFINED
#define SkOnce_DEFINED
// Before trying SkOnce, see if SkLazyPtr or SkLazyFnPtr will work for you.
// They're smaller and faster, if slightly less versatile.
// SkOnce.h defines SK_DECLARE_STATIC_ONCE and SkOnce(), which you can use
// together to create a threadsafe way to call a function just once. This
// is particularly useful for lazy singleton initialization. E.g.
// together to create a threadsafe way to call a function just once. E.g.
//
// static void set_up_my_singleton(Singleton** singleton) {
// *singleton = new Singleton(...);
// static void register_my_stuff(GlobalRegistry* registry) {
// registry->register(...);
// }
// ...
// const Singleton& GetSingleton() {
// static Singleton* singleton = NULL;
// void EnsureRegistered() {
// SK_DECLARE_STATIC_ONCE(once);
// SkOnce(&once, set_up_my_singleton, &singleton);
// SkASSERT(NULL != singleton);
// return *singleton;
// SkOnce(&once, register_my_stuff, GetGlobalRegistry());
// }
//
// No matter how many times you call EnsureRegistered(), register_my_stuff will be called just once.
// OnceTest.cpp also should serve as a few other simple examples.
//
// You may optionally pass SkOnce a second function to be called at exit for cleanup.
#include "SkDynamicAnnotations.h"
#include "SkThread.h"
#include "SkTypes.h"
#define SK_ONCE_INIT { false, { 0, SkDEBUGCODE(0) } }
#define SK_DECLARE_STATIC_ONCE(name) static SkOnceFlag name = SK_ONCE_INIT
// This must be used in a global or function scope, not as a class member.
#define SK_DECLARE_STATIC_ONCE(name) static SkOnceFlag name
struct SkOnceFlag; // If manually created, initialize with SkOnceFlag once = SK_ONCE_INIT
class SkOnceFlag;
template <typename Func, typename Arg>
inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)() = NULL);
inline void SkOnce(SkOnceFlag* once, void (*f)());
template <typename Arg>
inline void SkOnce(SkOnceFlag* once, void (*f)(Arg), Arg arg);
// If you've already got a lock and a flag to use, this variant lets you avoid an extra SkOnceFlag.
template <typename Lock, typename Func, typename Arg>
inline void SkOnce(bool* done, Lock* lock, Func f, Arg arg, void(*atExit)() = NULL);
template <typename Lock>
inline void SkOnce(bool* done, Lock* lock, void (*f)());
template <typename Lock, typename Arg>
inline void SkOnce(bool* done, Lock* lock, void (*f)(Arg), Arg arg);
// ---------------------- Implementation details below here. -----------------------------
// This is POD and must be zero-initialized.
struct SkSpinlock {
// This class has no constructor and must be zero-initialized (the macro above does this).
class SkOnceFlag {
public:
bool* mutableDone() { return &fDone; }
void acquire() {
SkASSERT(shouldBeZero == 0);
// No memory barrier needed, but sk_atomic_cas gives us at least release anyway.
while (!sk_atomic_cas(&thisIsPrivate, 0, 1)) {
// To act as a mutex, this needs an acquire barrier on success.
// sk_atomic_cas doesn't guarantee this ...
while (!sk_atomic_cas(&fSpinlock, 0, 1)) {
// spin
}
// ... so make sure to issue one of our own.
SkAssertResult(sk_acquire_load(&fSpinlock));
}
void release() {
SkASSERT(shouldBeZero == 0);
// This requires a release memory barrier before storing, which sk_atomic_cas guarantees.
SkAssertResult(sk_atomic_cas(&thisIsPrivate, 1, 0));
// To act as a mutex, this needs a release barrier. sk_atomic_cas guarantees this.
SkAssertResult(sk_atomic_cas(&fSpinlock, 1, 0));
}
int32_t thisIsPrivate;
SkDEBUGCODE(int32_t shouldBeZero;)
};
struct SkOnceFlag {
bool done;
SkSpinlock lock;
};
// TODO(bungeman, mtklein): move all these *barrier* functions to SkThread when refactoring lands.
#ifdef SK_BUILD_FOR_WIN
# include <intrin.h>
inline static void compiler_barrier() {
_ReadWriteBarrier();
}
#else
inline static void compiler_barrier() {
asm volatile("" : : : "memory");
}
#endif
inline static void full_barrier_on_arm() {
#ifdef SK_CPU_ARM
# if SK_ARM_ARCH >= 7
asm volatile("dmb" : : : "memory");
# else
asm volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
# endif
#endif
}
// On every platform, we issue a compiler barrier to prevent it from reordering
// code. That's enough for platforms like x86 where release and acquire
// barriers are no-ops. On other platforms we may need to be more careful;
// ARM, in particular, needs real code for both acquire and release. We use a
// full barrier, which acts as both, because that the finest precision ARM
// provides.
inline static void release_barrier() {
compiler_barrier();
full_barrier_on_arm();
}
inline static void acquire_barrier() {
compiler_barrier();
full_barrier_on_arm();
}
// Works with SkSpinlock or SkMutex.
template <typename Lock>
class SkAutoLockAcquire {
public:
explicit SkAutoLockAcquire(Lock* lock) : fLock(lock) { fLock->acquire(); }
~SkAutoLockAcquire() { fLock->release(); }
private:
Lock* fLock;
bool fDone;
int32_t fSpinlock;
};
// We've pulled a pretty standard double-checked locking implementation apart
@ -128,14 +82,11 @@ private:
// This is the guts of the code, called when we suspect the one-time code hasn't been run yet.
// This should be rarely called, so we separate it from SkOnce and don't mark it as inline.
// (We don't mind if this is an actual function call, but odds are it'll be inlined anyway.)
template <typename Lock, typename Func, typename Arg>
static void sk_once_slow(bool* done, Lock* lock, Func f, Arg arg, void (*atExit)()) {
const SkAutoLockAcquire<Lock> locked(lock);
template <typename Lock, typename Arg>
static void sk_once_slow(bool* done, Lock* lock, void (*f)(Arg), Arg arg) {
lock->acquire();
if (!*done) {
f(arg);
if (atExit != NULL) {
atexit(atExit);
}
// Also known as a store-store/load-store barrier, this makes sure that the writes
// done before here---in particular, those done by calling f(arg)---are observable
// before the writes after the line, *done = true.
@ -145,35 +96,49 @@ static void sk_once_slow(bool* done, Lock* lock, Func f, Arg arg, void (*atExit)
//
// We'll use this in the fast path to make sure f(arg)'s effects are
// observable whenever we observe *done == true.
release_barrier();
*done = true;
sk_release_store(done, true);
}
lock->release();
}
// This is our fast path, called all the time. We do really want it to be inlined.
template <typename Lock, typename Func, typename Arg>
inline void SkOnce(bool* done, Lock* lock, Func f, Arg arg, void(*atExit)()) {
template <typename Lock, typename Arg>
inline void SkOnce(bool* done, Lock* lock, void (*f)(Arg), Arg arg) {
if (!SK_ANNOTATE_UNPROTECTED_READ(*done)) {
sk_once_slow(done, lock, f, arg, atExit);
sk_once_slow(done, lock, f, arg);
}
// Also known as a load-load/load-store barrier, this acquire barrier makes
// sure that anything we read from memory---in particular, memory written by
// calling f(arg)---is at least as current as the value we read from once->done.
// calling f(arg)---is at least as current as the value we read from done.
//
// In version control terms, this is a lot like saying "sync up to the
// commit where we wrote once->done = true".
// commit where we wrote done = true".
//
// The release barrier in sk_once_slow guaranteed that once->done = true
// happens after f(arg), so by syncing to once->done = true here we're
// The release barrier in sk_once_slow guaranteed that done = true
// happens after f(arg), so by syncing to done = true here we're
// forcing ourselves to also wait until the effects of f(arg) are readble.
acquire_barrier();
SkAssertResult(sk_acquire_load(done));
}
template <typename Func, typename Arg>
inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)()) {
return SkOnce(&once->done, &once->lock, f, arg, atExit);
template <typename Arg>
inline void SkOnce(SkOnceFlag* once, void (*f)(Arg), Arg arg) {
return SkOnce(once->mutableDone(), once, f, arg);
}
#undef SK_ANNOTATE_BENIGN_RACE
// Calls its argument.
// This lets us use functions that take no arguments with SkOnce methods above.
// (We pass _this_ as the function and the no-arg function as its argument. Cute eh?)
static void sk_once_no_arg_adaptor(void (*f)()) {
f();
}
inline void SkOnce(SkOnceFlag* once, void (*func)()) {
return SkOnce(once, sk_once_no_arg_adaptor, func);
}
template <typename Lock>
inline void SkOnce(bool* done, Lock* lock, void (*func)()) {
return SkOnce(done, lock, sk_once_no_arg_adaptor, func);
}
#endif // SkOnce_DEFINED

View File

@ -52,14 +52,6 @@ typedef const SkGlyph& (*SkMeasureCacheProc)(SkGlyphCache*, const char**);
*/
class SK_API SkPaint {
enum {
// DEPRECATED -- use setFilterLevel instead
kFilterBitmap_Flag = 0x02, // temporary flag
// DEPRECATED -- use setFilterLevel instead
kHighQualityFilterBitmap_Flag = 0x4000, // temporary flag
// DEPRECATED -- use setFilterLevel instead
kHighQualityDownsampleBitmap_Flag = 0x8000, // temporary flag
};
public:
SkPaint();
SkPaint(const SkPaint& paint);
@ -97,7 +89,7 @@ public:
};
Hinting getHinting() const {
return static_cast<Hinting>(fHinting);
return static_cast<Hinting>(fBitfields.fHinting);
}
void setHinting(Hinting hintingLevel);
@ -129,7 +121,7 @@ public:
/** Return the paint's flags. Use the Flag enum to test flag values.
@return the paint's flags (see enums ending in _Flag for bit masks)
*/
uint32_t getFlags() const { return fFlags; }
uint32_t getFlags() const { return fBitfields.fFlags; }
/** Set the paint's flags. Use the Flag enum to specific flag values.
@param flags The new flag bits for the paint (see Flags enum)
@ -310,7 +302,9 @@ public:
* Return the filter level. This affects the quality (and performance) of
* drawing scaled images.
*/
FilterLevel getFilterLevel() const;
FilterLevel getFilterLevel() const {
return (FilterLevel)fBitfields.fFilterLevel;
}
/**
* Set the filter level. This affects the quality (and performance) of
@ -358,7 +352,7 @@ public:
kFill_Style).
@return the paint's Style
*/
Style getStyle() const { return (Style)fStyle; }
Style getStyle() const { return (Style)fBitfields.fStyle; }
/** Set the paint's style, used for controlling how primitives'
geometries are interpreted (except for drawBitmap, which always assumes
@ -464,7 +458,7 @@ public:
@return the line cap style for the paint, used whenever the paint's
style is Stroke or StrokeAndFill.
*/
Cap getStrokeCap() const { return (Cap)fCapType; }
Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
/** Set the paint's stroke cap type.
@param cap set the paint's line cap style, used whenever the paint's
@ -476,7 +470,7 @@ public:
@return the paint's line join style, used whenever the paint's style is
Stroke or StrokeAndFill.
*/
Join getStrokeJoin() const { return (Join)fJoinType; }
Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
/** Set the paint's stroke join type.
@param join set the paint's line join style, used whenever the paint's
@ -514,7 +508,12 @@ public:
* once (e.g. bitmap tiling or gradient) and then change its transparency
* w/o having to modify the original shader... only the paint's alpha needs
* to be modified.
* <p />
*
* There is an exception to this only-respect-paint's-alpha rule: If the shader only generates
* alpha (e.g. SkShader::CreateBitmapShader(bitmap, ...) where bitmap's colortype is kAlpha_8)
* then the shader will use the paint's entire color to "colorize" its output (modulating the
* bitmap's alpha with the paint's color+alpha).
*
* Pass NULL to clear any previous shader.
* As a convenience, the parameter passed is also returned.
* If a previous shader exists, its reference count is decremented.
@ -688,7 +687,7 @@ public:
/** Return the paint's Align value for drawing text.
@return the paint's Align value for drawing text.
*/
Align getTextAlign() const { return (Align)fTextAlign; }
Align getTextAlign() const { return (Align)fBitfields.fTextAlign; }
/** Set the paint's text alignment.
@param align set the paint's Align value for drawing text.
@ -741,7 +740,9 @@ public:
kGlyphID_TextEncoding //!< the text parameters are glyph indices
};
TextEncoding getTextEncoding() const { return (TextEncoding)fTextEncoding; }
TextEncoding getTextEncoding() const {
return (TextEncoding)fBitfields.fTextEncoding;
}
void setTextEncoding(TextEncoding encoding);
@ -1041,10 +1042,6 @@ public:
private:
SkTypeface* fTypeface;
SkScalar fTextSize;
SkScalar fTextScaleX;
SkScalar fTextSkewX;
SkPathEffect* fPathEffect;
SkShader* fShader;
SkXfermode* fXfermode;
@ -1055,10 +1052,12 @@ private:
SkImageFilter* fImageFilter;
SkAnnotation* fAnnotation;
SkScalar fTextSize;
SkScalar fTextScaleX;
SkScalar fTextSkewX;
SkColor fColor;
SkScalar fWidth;
SkScalar fMiterLimit;
union {
struct {
// all of these bitfields should add up to 32
@ -1069,13 +1068,11 @@ private:
unsigned fStyle : 2;
unsigned fTextEncoding : 2; // 3 values
unsigned fHinting : 2;
//unsigned fFreeBits : 4;
};
uint32_t fBitfields;
unsigned fFilterLevel : 2;
//unsigned fFreeBits : 2;
} fBitfields;
uint32_t fBitfieldsUInt;
};
uint32_t getBitfields() const { return fBitfields; }
void setBitfields(uint32_t bitfields);
uint32_t fDirtyBits;
SkDrawCacheProc getDrawCacheProc() const;
@ -1085,7 +1082,8 @@ private:
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
int* count, SkRect* bounds) const;
SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*) const;
SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*,
bool ignoreGamma) const;
void descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix,
void (*proc)(SkTypeface*, const SkDescriptor*, void*),
@ -1120,9 +1118,6 @@ private:
static bool TooBigToUseCache(const SkMatrix& ctm, const SkMatrix& textM);
bool tooBigToUseCache() const;
bool tooBigToUseCache(const SkMatrix& ctm) const;
// Set flags/hinting/textSize up to use for drawing text as paths.
// Returns scale factor to restore the original textSize, since will will
// have change it to kCanonicalTextSizeForPaths.
@ -1135,12 +1130,14 @@ private:
}
friend class SkAutoGlyphCache;
friend class SkAutoGlyphCacheNoGamma;
friend class SkCanvas;
friend class SkDraw;
friend class SkGraphics; // So Term() can be called.
friend class SkPDFDevice;
friend class GrBitmapTextContext;
friend class GrDistanceFieldTextContext;
friend class GrStencilAndCoverTextContext;
friend class SkTextToPathIter;
friend class SkCanonicalizePaint;

View File

@ -0,0 +1,124 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPatch_DEFINED
#define SkPatch_DEFINED
#include "SkColor.h"
#include "SkPreConfig.h"
#include "SkPoint.h"
/**
* Class that represents a coons patch.
*/
class SK_API SkPatch {
public:
/**
* Structure that holds the vertex data related to the tessellation of a SkPatch. It is passed
* as a parameter to the function getVertexData which sets the points, colors and texture
* coordinates of the vertices and the indices for them to be drawn as triangles.
*/
struct VertexData {
int fVertexCount, fIndexCount;
SkPoint* fPoints;
SkPoint* fTexCoords;
uint32_t* fColors;
uint16_t* fIndices;
VertexData()
: fVertexCount(0)
, fIndexCount(0)
, fPoints(NULL)
, fTexCoords(NULL)
, fColors(NULL)
, fIndices(NULL) { }
~VertexData() {
SkDELETE_ARRAY(fPoints);
SkDELETE_ARRAY(fTexCoords);
SkDELETE_ARRAY(fColors);
SkDELETE_ARRAY(fIndices);
}
};
enum CubicCtrlPts {
kTopP0_CubicCtrlPts = 0,
kTopP1_CubicCtrlPts = 1,
kTopP2_CubicCtrlPts = 2,
kTopP3_CubicCtrlPts = 3,
kRightP0_CubicCtrlPts = 3,
kRightP1_CubicCtrlPts = 4,
kRightP2_CubicCtrlPts = 5,
kRightP3_CubicCtrlPts = 6,
kBottomP0_CubicCtrlPts = 9,
kBottomP1_CubicCtrlPts = 8,
kBottomP2_CubicCtrlPts = 7,
kBottomP3_CubicCtrlPts = 6,
kLeftP0_CubicCtrlPts = 0,
kLeftP1_CubicCtrlPts = 11,
kLeftP2_CubicCtrlPts = 10,
kLeftP3_CubicCtrlPts = 9,
};
/**
* Points are in the following order:
* (top curve)
* 0 1 2 3
* (left curve) 11 4 (right curve)
* 10 5
* 9 8 7 6
* (bottom curve)
* Used pointer to an array to guarantee that this method receives an array of 4 SkColors
*/
SkPatch(SkPoint points[12], SkColor colors[4]);
/**
* Function that evaluates the coons patch interpolation.
* data refers to the pointer of the PatchData struct in which the tessellation data is set.
* divisions defines the number of steps in which the SkPatch is going to be subdivided per
* axis.
*/
bool getVertexData(SkPatch::VertexData* data, int divisions);
void getTopPoints(SkPoint points[4]) {
points[0] = fCtrlPoints[kTopP0_CubicCtrlPts];
points[1] = fCtrlPoints[kTopP1_CubicCtrlPts];
points[2] = fCtrlPoints[kTopP2_CubicCtrlPts];
points[3] = fCtrlPoints[kTopP3_CubicCtrlPts];
}
void getBottomPoints(SkPoint points[4]) {
points[0] = fCtrlPoints[kBottomP0_CubicCtrlPts];
points[1] = fCtrlPoints[kBottomP1_CubicCtrlPts];
points[2] = fCtrlPoints[kBottomP2_CubicCtrlPts];
points[3] = fCtrlPoints[kBottomP3_CubicCtrlPts];
}
void getLeftPoints(SkPoint points[4]) {
points[0] = fCtrlPoints[kLeftP0_CubicCtrlPts];
points[1] = fCtrlPoints[kLeftP1_CubicCtrlPts];
points[2] = fCtrlPoints[kLeftP2_CubicCtrlPts];
points[3] = fCtrlPoints[kLeftP3_CubicCtrlPts];
}
void getRightPoints(SkPoint points[4]) {
points[0] = fCtrlPoints[kRightP0_CubicCtrlPts];
points[1] = fCtrlPoints[kRightP1_CubicCtrlPts];
points[2] = fCtrlPoints[kRightP2_CubicCtrlPts];
points[3] = fCtrlPoints[kRightP3_CubicCtrlPts];
}
private:
SkPoint fCtrlPoints[12];
SkPMColor fCornerColors[4];
};
#endif

View File

@ -21,6 +21,7 @@ class SkWriter32;
class SkAutoPathBoundsUpdate;
class SkString;
class SkRRect;
class SkWStream;
/** \class SkPath
@ -930,7 +931,7 @@ public:
*/
bool contains(SkScalar x, SkScalar y) const;
void dump(bool forceClose, const char title[] = NULL) const;
void dump(SkWStream* , bool forceClose) const;
void dump() const;
/**

View File

@ -104,6 +104,33 @@ public:
const SkStrokeRec&, const SkMatrix&,
const SkRect* cullR) const;
/**
* If the PathEffect can be represented as a dash pattern, asADash will return kDash_DashType
* and None otherwise. If a non NULL info is passed in, the various DashInfo will be filled
* in if the PathEffect can be a dash pattern. If passed in info has an fCount equal or
* greater to that of the effect, it will memcpy the values of the dash intervals into the
* info. Thus the general approach will be call asADash once with default info to get DashType
* and fCount. If effect can be represented as a dash pattern, allocate space for the intervals
* in info, then call asADash again with the same info and the intervals will get copied in.
*/
enum DashType {
kNone_DashType, //!< ignores the info parameter
kDash_DashType, //!< fills in all of the info parameter
};
struct DashInfo {
DashInfo() : fIntervals(NULL), fCount(0), fPhase(0) {}
SkScalar* fIntervals; //!< Length of on/off intervals for dashed lines
// Even values represent ons, and odds offs
int32_t fCount; //!< Number of intervals in the dash. Should be even number
SkScalar fPhase; //!< Offset into the dashed interval pattern
// mod the sum of all intervals
};
virtual DashType asADash(DashInfo* info) const;
SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect)
protected:
@ -162,13 +189,9 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
protected:
SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner)
: INHERITED(outer, inner) {}
explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
private:
// illegal
@ -200,13 +223,9 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
protected:
SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkSumPathEffect(SkPathEffect* first, SkPathEffect* second)
: INHERITED(first, second) {}
explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {}
private:
// illegal

View File

@ -9,6 +9,7 @@
#ifndef SkPathRef_DEFINED
#define SkPathRef_DEFINED
#include "SkDynamicAnnotations.h"
#include "SkMatrix.h"
#include "SkPoint.h"
#include "SkRect.h"
@ -290,9 +291,11 @@ private:
// called, if dirty, by getBounds()
void computeBounds() const {
SkDEBUGCODE(this->validate();)
SkASSERT(fBoundsIsDirty);
// TODO(mtklein): remove fBoundsIsDirty and fIsFinite,
// using an inverted rect instead of fBoundsIsDirty and always recalculating fIsFinite.
//SkASSERT(fBoundsIsDirty);
fIsFinite = ComputePtBounds(&fBounds, *this);
fIsFinite = ComputePtBounds(fBounds.get(), *this);
fBoundsIsDirty = false;
}
@ -300,7 +303,7 @@ private:
SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
fBounds = rect;
fBoundsIsDirty = false;
fIsFinite = fBounds.isFinite();
fIsFinite = fBounds->isFinite();
}
/** Makes additional room but does not change the counts or change the genID */
@ -418,7 +421,7 @@ private:
/**
* Called the first time someone calls CreateEmpty to actually create the singleton.
*/
static void CreateEmptyImpl(int/*unused*/);
static SkPathRef* CreateEmptyImpl();
void setIsOval(bool isOval) { fIsOval = isOval; }
@ -432,11 +435,12 @@ private:
kMinSize = 256,
};
mutable SkRect fBounds;
uint8_t fSegmentMask;
mutable uint8_t fBoundsIsDirty;
mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
mutable SkBool8 fIsOval;
mutable SkTRacyReffable<SkRect> fBounds;
mutable SkTRacy<uint8_t> fBoundsIsDirty;
mutable SkTRacy<SkBool8> fIsFinite; // only meaningful if bounds are valid
SkBool8 fIsOval;
uint8_t fSegmentMask;
SkPoint* fPoints; // points to begining of the allocation
uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards)

View File

@ -11,20 +11,28 @@
#define SkPicture_DEFINED
#include "SkBitmap.h"
#include "SkDrawPictureCallback.h"
#include "SkImageDecoder.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"
#if SK_SUPPORT_GPU
class GrContext;
#endif
class SkBBHFactory;
class SkBBoxHierarchy;
class SkCanvas;
class SkDrawPictureCallback;
class SkData;
class SkPicturePlayback;
class SkPictureData;
class SkPictureRecord;
class SkStream;
class SkWStream;
struct SkPictInfo;
class SkRecord;
/** \class SkPicture
The SkPicture class records the drawing commands made to a canvas, to
@ -55,27 +63,15 @@ public:
typedef SkRefCnt INHERITED;
};
/** The constructor prepares the picture to record.
@param width the width of the virtual device the picture records.
@param height the height of the virtual device the picture records.
*/
#ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR
SkPicture();
/** Make a copy of the contents of src. If src records more drawing after
this call, those elements will not appear in this picture.
*/
SkPicture(const SkPicture& src);
#endif
/** PRIVATE / EXPERIMENTAL -- do not call */
void EXPERIMENTAL_addAccelData(const AccelData* data) {
SkRefCnt_SafeAssign(fAccelData, data);
}
void EXPERIMENTAL_addAccelData(const AccelData*) const;
/** PRIVATE / EXPERIMENTAL -- do not call */
const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const {
if (NULL != fAccelData && fAccelData->getKey() == key) {
return fAccelData;
}
return NULL;
}
const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key) const;
/**
* Function signature defining a function that sets up an SkBitmap from encoded data. On
@ -113,79 +109,17 @@ public:
virtual ~SkPicture();
/**
* Swap the contents of the two pictures. Guaranteed to succeed.
*/
void swap(SkPicture& other);
#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE
/**
* Creates a thread-safe clone of the picture that is ready for playback.
*/
SkPicture* clone() const;
#endif
/**
* Creates multiple thread-safe clones of this picture that are ready for
* playback. The resulting clones are stored in the provided array of
* SkPictures.
*/
void clone(SkPicture* pictures, int count) const;
enum RecordingFlags {
/* This flag specifies that when clipPath() is called, the path will
be faithfully recorded, but the recording canvas' current clip will
only see the path's bounds. This speeds up the recording process
without compromising the fidelity of the playback. The only side-
effect for recording is that calling getTotalClip() or related
clip-query calls will reflect the path's bounds, not the actual
path.
*/
kUsePathBoundsForClip_RecordingFlag = 0x01,
/* This flag causes the picture to compute bounding boxes and build
up a spatial hierarchy (currently an R-Tree), plus a tree of Canvas'
usually stack-based clip/etc state. This requires an increase in
recording time (often ~2x; likely more for very complex pictures),
but allows us to perform much faster culling at playback time, and
completely avoid some unnecessary clips and other operations. This
is ideal for tiled rendering, or any other situation where you're
drawing a fraction of a large scene into a smaller viewport.
In most cases the record cost is offset by the playback improvement
after a frame or two of tiled rendering (and complex pictures that
induce the worst record times will generally get the largest
speedups at playback time).
Note: Currently this is not serializable, the bounding data will be
discarded if you serialize into a stream and then deserialize.
*/
kOptimizeForClippedPlayback_RecordingFlag = 0x02,
};
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@param height the base width for the picture, as if the recording
canvas' bitmap had this height.
@param recordFlags optional flags that control recording.
@return the picture canvas.
*/
SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
SkCanvas* getRecordingCanvas() const;
/** Signal that the caller is done recording. This invalidates the canvas
returned by beginRecording/getRecordingCanvas, and prepares the picture
for drawing. Note: this happens implicitly the first time the picture
is drawn.
*/
void endRecording();
/** Replays the drawing commands on the specified canvas. This internally
calls endRecording() if that has not already been called.
/** Replays the drawing commands on the specified canvas.
@param canvas the canvas receiving the drawing commands.
*/
void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL);
void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const;
/** Return the width of the picture's recording canvas. This
value reflects what was passed to setSize(), and does not necessarily
@ -201,6 +135,13 @@ public:
*/
int height() const { return fHeight; }
/** Return a non-zero, unique value representing the picture. This call is
only valid when not recording. Between a beginRecording/endRecording
pair it will just return 0 (the invalid ID). Each beginRecording/
endRecording pair will cause a different generation ID to be returned.
*/
uint32_t uniqueID() const;
/**
* Function to encode an SkBitmap to an SkData. A function with this
* signature can be passed to serialize() and SkWriteBuffer.
@ -228,19 +169,9 @@ public:
/**
* Returns true if any bitmaps may be produced when this SkPicture
* is replayed.
* Returns false if called while still recording.
*/
bool willPlayBackBitmaps() const;
#ifdef SK_BUILD_FOR_ANDROID
/** Signals that the caller is prematurely done replaying the drawing
commands. This can be called from a canvas virtual while the picture
is drawing. Has no effect if the picture is not drawing.
@deprecated preserving for legacy purposes
*/
void abortPlayback();
#endif
/** Return true if the SkStream/Buffer represents a serialized picture, and
fills out SkPictInfo. After this function returns, the data source is not
rewound so it will have to be manually reset before passing to
@ -252,15 +183,22 @@ public:
static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*);
static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*);
/** Enable/disable all the picture recording optimizations (i.e.,
those in SkPictureRecord). It is mainly intended for testing the
existing optimizations (i.e., to actually have the pattern
appear in an .skp we have to disable the optimization). Call right
after 'beginRecording'.
*/
void internalOnly_EnableOpts(bool enableOpts);
/** Return true if the picture is suitable for rendering on the GPU.
*/
protected:
#if SK_SUPPORT_GPU
bool suitableForGpuRasterization(GrContext*, const char ** = NULL) const;
#endif
class DeletionListener : public SkRefCnt {
public:
virtual void onDeletion(uint32_t pictureID) = 0;
};
// Takes ref on listener.
void addDeletionListener(DeletionListener* listener) const;
private:
// V2 : adds SkPixelRef's generation ID.
// V3 : PictInfo tag at beginning, and EOF tag at the end
// V4 : move SkPictInfo to be the header
@ -276,7 +214,7 @@ protected:
// V13: add flag to drawBitmapRectToRect
// parameterize blurs by sigma rather than radius
// V14: Add flags word to PathRef serialization
// V15: Remove A1 bitmpa config (and renumber remaining configs)
// V15: Remove A1 bitmap config (and renumber remaining configs)
// V16: Move SkPath's isOval flag to SkPathRef
// V17: SkPixelRef now writes SkImageInfo
// V18: SkBitmap now records x,y for its pixelref origin, instead of offset.
@ -284,55 +222,75 @@ protected:
// V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization)
// V21: add pushCull, popCull
// V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes
// V23: SkPaint::FilterLevel became a real enum
// V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping
// V25: SkDashPathEffect now only writes phase and interval array when flattening
// V26: Removed boolean from SkColorShader for inheriting color from SkPaint.
// V27: Remove SkUnitMapper from gradients (and skia).
// V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap.
// V29: Removed SaveFlags parameter from save().
// V30: Remove redundant SkMatrix from SkLocalMatrixShader.
// Note: If the picture version needs to be increased then please follow the
// steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw
// Only SKPs within the min/current picture version range (inclusive) can be read.
static const uint32_t MIN_PICTURE_VERSION = 19;
static const uint32_t CURRENT_PICTURE_VERSION = 22;
static const uint32_t CURRENT_PICTURE_VERSION = 30;
// fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to
// install their own SkPicturePlayback-derived players,SkPictureRecord-derived
// recorders and set the picture size
SkPicturePlayback* fPlayback;
SkPictureRecord* fRecord;
mutable uint32_t fUniqueID;
// TODO: make SkPictureData const when clone method goes away
SkAutoTDelete<SkPictureData> fData;
int fWidth, fHeight;
const AccelData* fAccelData;
mutable SkAutoTUnref<const AccelData> fAccelData;
// Create a new SkPicture from an existing SkPicturePlayback. Ref count of
// playback is unchanged.
SkPicture(SkPicturePlayback*, int width, int height);
mutable SkTDArray<DeletionListener*> fDeletionListeners; // pointers are refed
void needsNewGenID() { fUniqueID = SK_InvalidGenID; }
void callDeletionListeners();
// Create a new SkPicture from an existing SkPictureData. The new picture
// takes ownership of 'data'.
SkPicture(SkPictureData* data, int width, int height);
SkPicture(int width, int height, const SkPictureRecord& record, bool deepCopyOps);
// An OperationList encapsulates a set of operation offsets into the picture byte
// stream along with the CTMs needed for those operation.
class OperationList : ::SkNoncopyable {
public:
// The following three entry points should only be accessed if
// 'valid' returns true.
int numOps() const { return fOps.count(); }
// The offset in the picture of the operation to execute.
uint32_t offset(int index) const;
// The CTM that must be installed for the operation to behave correctly
const SkMatrix& matrix(int index) const;
SkTDArray<void*> fOps;
};
/** PRIVATE / EXPERIMENTAL -- do not call
Return the operations required to render the content inside 'queryRect'.
*/
const OperationList* EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const;
// For testing. Derived classes may instantiate an alternate
// SkBBoxHierarchy implementation
virtual SkBBoxHierarchy* createBBoxHierarchy() const;
private:
void createHeader(SkPictInfo* info) const;
static bool IsValidPictInfo(const SkPictInfo& info);
friend class SkFlatPicture;
friend class SkPicturePlayback;
friend class SkPictureData; // to access OperationList
friend class SkPictureRecorder; // just for SkPicture-based constructor
friend class SkGpuDevice; // for EXPERIMENTAL_getActiveOps/OperationList
friend class GrGatherCanvas; // needs to know if old or new picture
friend class SkPicturePlayback; // to get fData & OperationList
friend class SkPictureReplacementPlayback; // to access OperationList
typedef SkRefCnt INHERITED;
};
/**
* Subclasses of this can be passed to canvas.drawPicture. During the drawing
* of the picture, this callback will periodically be invoked. If its
* abortDrawing() returns true, then picture playback will be interrupted.
*
* The resulting drawing is undefined, as there is no guarantee how often the
* callback will be invoked. If the abort happens inside some level of nested
* calls to save(), restore will automatically be called to return the state
* to the same level it was before the drawPicture call was made.
*/
class SK_API SkDrawPictureCallback {
public:
SkDrawPictureCallback() {}
virtual ~SkDrawPictureCallback() {}
virtual bool abortDrawing() = 0;
SkPicture(int width, int height, SkRecord*); // Takes ownership.
SkAutoTDelete<SkRecord> fRecord;
bool fRecordWillPlayBackBitmaps; // TODO: const
};
#endif

View File

@ -0,0 +1,93 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPictureRecorder_DEFINED
#define SkPictureRecorder_DEFINED
#include "SkBBHFactory.h"
#include "SkPicture.h"
#include "SkRefCnt.h"
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
namespace android {
class Picture;
};
#endif
class SkCanvas;
class SkPictureRecord;
class SkRecord;
class SkRecorder;
class SK_API SkPictureRecorder : SkNoncopyable {
public:
SkPictureRecorder();
~SkPictureRecorder();
/** Returns the canvas that records the drawing commands.
@param width the base width for the picture, as if the recording
canvas' bitmap had this width.
@param height the base width for the picture, as if the recording
canvas' bitmap had this height.
@param bbhFactory factory to create desired acceleration structure
@param recordFlags optional flags that control recording.
@return the canvas.
*/
SkCanvas* beginRecording(int width, int height,
SkBBHFactory* bbhFactory = NULL,
uint32_t recordFlags = 0);
/** Same as beginRecording(), using a new faster backend. */
SkCanvas* EXPERIMENTAL_beginRecording(int width, int height,
SkBBHFactory* bbhFactory = NULL);
/** Returns the recording canvas if one is active, or NULL if recording is
not active. This does not alter the refcnt on the canvas (if present).
*/
SkCanvas* getRecordingCanvas();
/** Signal that the caller is done recording. This invalidates the canvas
returned by beginRecording/getRecordingCanvas, and returns the
created SkPicture. Note that the returned picture has its creation
ref which the caller must take ownership of.
*/
SkPicture* endRecording();
/** Enable/disable all the picture recording optimizations (i.e.,
those in SkPictureRecord). It is mainly intended for testing the
existing optimizations (i.e., to actually have the pattern
appear in an .skp we have to disable the optimization). Call right
after 'beginRecording'.
*/
void internalOnly_EnableOpts(bool enableOpts);
private:
void reset();
/** Replay the current (partially recorded) operation stream into
canvas. This call doesn't close the current recording.
*/
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
friend class android::Picture;
#endif
friend class SkPictureRecorderReplayTester; // for unit testing
void partialReplay(SkCanvas* canvas) const;
int fWidth;
int fHeight;
// One of these two canvases will be non-NULL.
SkAutoTUnref<SkPictureRecord> fPictureRecord; // beginRecording()
SkAutoTUnref<SkRecorder> fRecorder; // EXPERIMENTAL_beginRecording()
// Used by EXPERIMENTAL_beginRecording().
SkAutoTDelete<SkRecord> fRecord;
typedef SkNoncopyable INHERITED;
};
#endif

View File

@ -9,10 +9,11 @@
#define SkPixelRef_DEFINED
#include "SkBitmap.h"
#include "SkDynamicAnnotations.h"
#include "SkRefCnt.h"
#include "SkString.h"
#include "SkFlattenable.h"
#include "SkImageInfo.h"
#include "SkSize.h"
#include "SkTDArray.h"
//#define xed
@ -46,7 +47,7 @@ class GrTexture;
This class can be shared/accessed between multiple threads.
*/
class SK_API SkPixelRef : public SkFlattenable {
class SK_API SkPixelRef : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkPixelRef)
@ -219,18 +220,30 @@ public:
*/
virtual GrTexture* getTexture() { return NULL; }
/**
* If any planes or rowBytes is NULL, this should output the sizes and return true
* if it can efficiently return YUV planar data. If it cannot, it should return false.
*
* If all planes and rowBytes are not NULL, then it should copy the associated Y,U,V data
* into those planes of memory supplied by the caller. It should validate that the sizes
* match what it expected. If the sizes do not match, it should return false.
*/
bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) {
return this->onGetYUV8Planes(sizes, planes, rowBytes);
}
bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
/**
* Makes a deep copy of this PixelRef, respecting the requested config.
* @param config Desired config.
* @param colorType Desired colortype.
* @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of
* of this PixelRef.
* @return A new SkPixelRef, or 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, const SkIRect* subset = NULL) {
virtual SkPixelRef* deepCopy(SkColorType colortype, const SkIRect* subset) {
return NULL;
}
@ -250,8 +263,6 @@ public:
virtual void globalUnref();
#endif
SK_DEFINE_FLATTENABLE_TYPE(SkPixelRef)
// Register a listener that may be called the next time our generation ID changes.
//
// We'll only call the listener if we're confident that we are the only SkPixelRef with this
@ -307,6 +318,9 @@ protected:
// default impl returns NULL.
virtual SkData* onRefEncodedData();
// default impl returns false.
virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]);
/**
* Returns the size (in bytes) of the internally allocated memory.
* This should be implemented in all serializable SkPixelRef derived classes.
@ -322,10 +336,6 @@ protected:
*/
SkBaseMutex* mutex() const { return fMutex; }
// serialization
SkPixelRef(SkReadBuffer&, SkBaseMutex*);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
// only call from constructor. Flags this to always be locked, removing
// the need to grab the mutex and call onLockPixels/onUnlockPixels.
// Performance tweak to avoid those calls (esp. in multi-thread use case).
@ -341,8 +351,8 @@ private:
LockRec fRec;
int fLockCount;
mutable uint32_t fGenerationID;
mutable bool fUniqueGenerationID;
mutable SkTRacy<uint32_t> fGenerationID;
mutable SkTRacy<bool> fUniqueGenerationID;
SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owned
@ -363,7 +373,7 @@ private:
friend class SkBitmap; // only for cloneGenID
void cloneGenID(const SkPixelRef&);
typedef SkFlattenable INHERITED;
typedef SkRefCnt INHERITED;
};
class SkPixelRefFactory : public SkRefCnt {
@ -374,7 +384,7 @@ public:
* the pixelref will ref() the colortable.
* On failure return NULL.
*/
virtual SkPixelRef* create(const SkImageInfo&, SkColorTable*) = 0;
virtual SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) = 0;
};
#endif

View File

@ -11,6 +11,28 @@
#include "SkMath.h"
#include "SkScalar.h"
/** \struct SkIPoint16
SkIPoint holds two 16 bit integer coordinates
*/
struct SkIPoint16 {
int16_t fX, fY;
static SkIPoint16 Make(int x, int y) {
SkIPoint16 pt;
pt.set(x, y);
return pt;
}
int16_t x() const { return fX; }
int16_t y() const { return fY; }
void set(int x, int y) {
fX = SkToS16(x);
fY = SkToS16(y);
}
};
/** \struct SkIPoint
SkIPoint holds two 32 bit integer coordinates

View File

@ -107,10 +107,14 @@
#endif
#ifndef SK_CRASH
# if 1 // set to 0 for infinite loop, which can help connecting gdb
# define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
# ifdef SK_BUILD_FOR_WIN
# define SK_CRASH() __debugbreak()
# else
# define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
# if 1 // set to 0 for infinite loop, which can help connecting gdb
# define SK_CRASH() do { SkNO_RETURN_HINT(); *(int *)(uintptr_t)0xbbadbeef = 0; } while (false)
# else
# define SK_CRASH() do { SkNO_RETURN_HINT(); } while (true)
# endif
# endif
#endif
@ -154,10 +158,6 @@
# undef NOMINMAX
# endif
#
# ifndef SK_DEBUGBREAK
# define SK_DEBUGBREAK(p) do { if (!(p)) { SkNO_RETURN_HINT(); __debugbreak(); }} while (false)
# endif
#
# ifndef SK_A32_SHIFT
# define SK_A32_SHIFT 24
# define SK_R32_SHIFT 16
@ -165,14 +165,18 @@
# define SK_B32_SHIFT 0
# endif
#
#else
#endif
#ifndef SK_ALWAYSBREAK
# ifdef SK_DEBUG
# include <stdio.h>
# ifndef SK_DEBUGBREAK
# define SK_DEBUGBREAK(cond) do { if (cond) break; \
SkDebugf("%s:%d: failed assertion \"%s\"\n", \
__FILE__, __LINE__, #cond); SK_CRASH(); } while (false)
# endif
# define SK_ALWAYSBREAK(cond) do { \
if (cond) break; \
SkNO_RETURN_HINT(); \
SkDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \
SK_CRASH(); \
} while (false)
# else
# define SK_ALWAYSBREAK(cond) do { if (cond) break; SK_CRASH(); } while (false)
# endif
#endif
@ -321,6 +325,14 @@
# define SK_ATTR_DEPRECATED(msg) SK_ATTRIBUTE(deprecated)
#endif
#if !defined(SK_ATTR_EXTERNALLY_DEPRECATED)
# if !defined(SK_INTERNAL)
# define SK_ATTR_EXTERNALLY_DEPRECATED(msg) SK_ATTR_DEPRECATED(msg)
# else
# define SK_ATTR_EXTERNALLY_DEPRECATED(msg)
# endif
#endif
/**
* If your judgment is better than the compiler's (i.e. you've profiled it),
* you can use SK_ALWAYS_INLINE to force inlining. E.g.
@ -376,8 +388,6 @@
#ifndef SK_ATOMICS_PLATFORM_H
# if defined(_MSC_VER)
# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h"
# elif defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_android.h"
# else
# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h"
# endif
@ -391,4 +401,25 @@
# endif
#endif
#ifndef SK_BARRIERS_PLATFORM_H
# if SK_HAS_COMPILER_FEATURE(thread_sanitizer)
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_tsan.h"
# elif defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64)
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h"
# else
# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h"
# endif
#endif
//////////////////////////////////////////////////////////////////////
#if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB)
# error "cannot define both SK_GAMMA_EXPONENT and SK_GAMMA_SRGB"
#elif defined(SK_GAMMA_SRGB)
# define SK_GAMMA_EXPONENT (0.0f)
#elif !defined(SK_GAMMA_EXPONENT)
# define SK_GAMMA_EXPONENT (2.2f)
#endif
#endif // SkPostConfig_DEFINED

View File

@ -92,9 +92,15 @@
//////////////////////////////////////////////////////////////////////
#if !defined(SK_CPU_BENDIAN) && !defined(SK_CPU_LENDIAN)
#if defined (__ppc__) || defined(__PPC__) || defined(__ppc64__) \
|| defined(__PPC64__)
#define SK_CPU_BENDIAN
#if defined(__sparc) || defined(__sparc__) || \
defined(_POWER) || defined(__powerpc__) || \
defined(__ppc__) || defined(__hppa) || \
defined(__PPC__) || defined(__PPC64__) || \
defined(_MIPSEB) || defined(__ARMEB__) || \
defined(__s390__) || \
(defined(__sh__) && defined(__BIG_ENDIAN__)) || \
(defined(__ia64) && defined(__BIG_ENDIAN__))
#define SK_CPU_BENDIAN
#else
#define SK_CPU_LENDIAN
#endif
@ -102,6 +108,10 @@
//////////////////////////////////////////////////////////////////////
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
#define SK_CPU_X86 1
#endif
/**
* SK_CPU_SSE_LEVEL
*
@ -113,12 +123,18 @@
#define SK_CPU_SSE_LEVEL_SSE2 20
#define SK_CPU_SSE_LEVEL_SSE3 30
#define SK_CPU_SSE_LEVEL_SSSE3 31
#define SK_CPU_SSE_LEVEL_SSE41 41
#define SK_CPU_SSE_LEVEL_SSE42 42
// Are we in GCC?
#ifndef SK_CPU_SSE_LEVEL
// These checks must be done in descending order to ensure we set the highest
// available SSE level.
#if defined(__SSSE3__)
#if defined(__SSE4_2__)
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42
#elif defined(__SSE4_1__)
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41
#elif defined(__SSSE3__)
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3
#elif defined(__SSE3__)
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3
@ -130,8 +146,10 @@
// Are we in VisualStudio?
#ifndef SK_CPU_SSE_LEVEL
// These checks must be done in descending order to ensure we set the highest
// available SSE level.
#if defined (_M_IX86_FP)
// available SSE level. 64-bit intel guarantees at least SSE2 support.
#if defined(_M_X64) || defined(_M_AMD64)
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
#elif defined (_M_IX86_FP)
#if _M_IX86_FP >= 2
#define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2
#elif _M_IX86_FP == 1
@ -144,7 +162,7 @@
// ARM defines
#if defined(__arm__) && (!defined(__APPLE__) || !TARGET_IPHONE_SIMULATOR)
#define SK_CPU_ARM
#define SK_CPU_ARM32
#if defined(__GNUC__)
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
@ -174,6 +192,11 @@
#endif
#endif
// Disable ARM64 optimizations for iOS due to complications regarding gyp and iOS.
#if defined(__aarch64__) && !defined(SK_BUILD_FOR_IOS)
#define SK_CPU_ARM64
#endif
//////////////////////////////////////////////////////////////////////
#if !defined(SKIA_IMPLEMENTATION)

View File

@ -71,6 +71,14 @@ public:
//!< the curves) nor a rect (i.e., both radii are non-zero)
kSimple_Type,
//!< The RR is non-empty and the two left x radii are equal, the two top
//!< y radii are equal, and the same for the right and bottom but it is
//!< neither an rect, oval, nor a simple RR. It is called "nine patch"
//!< because the centers of the corner ellipses form an axis aligned
//!< rect with edges that divide the RR into an 9 rectangular patches:
//!< an interior patch, four edge patches, and four corner patches.
kNinePatch_Type,
//!< A fully general (non-empty) RR. Some of the x and/or y radii are
//!< different from the others and there must be one corner where
//!< both radii are non-zero.
@ -99,21 +107,11 @@ public:
inline bool isSimpleCircular() const {
return this->isSimple() && fRadii[0].fX == fRadii[0].fY;
}
inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); }
inline bool isComplex() const { return kComplex_Type == this->getType(); }
bool allCornersCircular() const;
/**
* Are both x-radii the same on the two left corners, and similar for the top, right, and
* bottom. When this is the case the four ellipse centers form a rectangle.
*/
bool isNinePatch() const {
return fRadii[kUpperLeft_Corner].fX == fRadii[kLowerLeft_Corner].fX &&
fRadii[kUpperRight_Corner].fX == fRadii[kLowerRight_Corner].fX &&
fRadii[kUpperLeft_Corner].fY == fRadii[kUpperRight_Corner].fY &&
fRadii[kLowerLeft_Corner].fY == fRadii[kLowerRight_Corner].fY;
}
SkScalar width() const { return fRect.width(); }
SkScalar height() const { return fRect.height(); }
@ -171,6 +169,12 @@ public:
*/
void setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad);
/**
* Initialize the rr with one radius per-side.
*/
void setNinePatch(const SkRect& rect, SkScalar leftRad, SkScalar topRad,
SkScalar rightRad, SkScalar bottomRad);
/**
* Initialize the RR with potentially different radii for all four corners.
*/
@ -288,6 +292,14 @@ public:
*/
bool transform(const SkMatrix& matrix, SkRRect* dst) const;
#ifdef SK_DEVELOPER
/**
* Prints the rrect using SkDebugf. This is intended for Skia development debugging. Don't
* rely on the existence of this function or the formatting of its output.
*/
void dump() const;
#endif
private:
SkRect fRect;
// Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[]

View File

@ -1,4 +1,3 @@
/*
* Copyright 2011 Google Inc.
*
@ -18,13 +17,11 @@
#include "SkPath.h"
#include "SkPathEffect.h"
#include "SkPicture.h"
#include "SkPixelRef.h"
#include "SkRasterizer.h"
#include "SkReadBuffer.h"
#include "SkReader32.h"
#include "SkRefCnt.h"
#include "SkShader.h"
#include "SkUnitMapper.h"
#include "SkWriteBuffer.h"
#include "SkXfermode.h"
@ -41,6 +38,30 @@ public:
SkReadBuffer(SkStream* stream);
virtual ~SkReadBuffer();
enum Version {
kFilterLevelIsEnum_Version = 23,
kGradientFlippedFlag_Version = 24,
kDashWritesPhaseIntervals_Version = 25,
kColorShaderNoBool_Version = 26,
kNoUnitMappers_Version = 27,
kNoMoreBitmapFlatten_Version = 28,
kSimplifyLocalMatrix_Version = 30,
};
/**
* Returns true IFF the version is older than the specified version.
*/
bool isVersionLT(Version targetVersion) const {
SkASSERT(targetVersion > 0);
return fVersion > 0 && fVersion < targetVersion;
}
/** This may be called at most once; most clients of SkReadBuffer should not mess with it. */
void setVersion(int version) {
SkASSERT(0 == fVersion || version == fVersion);
fVersion = version;
}
enum Flags {
kCrossProcess_Flag = 1 << 0,
kScalarIsFloat_Flag = 1 << 1,
@ -60,10 +81,11 @@ public:
SkReader32* getReader32() { return &fReader; }
uint32_t size() { return fReader.size(); }
uint32_t offset() { return fReader.offset(); }
size_t size() { return fReader.size(); }
size_t offset() { return fReader.offset(); }
bool eof() { return fReader.eof(); }
const void* skip(size_t size) { return fReader.skip(size); }
virtual const void* skip(size_t size) { return fReader.skip(size); }
void* readFunctionPtr() { return fReader.readPtr(); }
// primitives
virtual bool readBool();
@ -74,12 +96,6 @@ public:
virtual uint32_t readUInt();
virtual int32_t read32();
void* readFunctionPtr() {
void* ptr;
this->readByteArray(&ptr, sizeof(ptr));
return ptr;
}
// strings -- the caller is responsible for freeing the string contents
virtual void readString(SkString* string);
virtual void* readEncodedString(size_t* length, SkPaint::TextEncoding encoding);
@ -103,12 +119,15 @@ public:
SkImageFilter* readImageFilter() { return this->readFlattenable<SkImageFilter>(); }
SkMaskFilter* readMaskFilter() { return this->readFlattenable<SkMaskFilter>(); }
SkPathEffect* readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
SkPixelRef* readPixelRef() { return this->readFlattenable<SkPixelRef>(); }
SkRasterizer* readRasterizer() { return this->readFlattenable<SkRasterizer>(); }
SkShader* readShader() { return this->readFlattenable<SkShader>(); }
SkUnitMapper* readUnitMapper() { return this->readFlattenable<SkUnitMapper>(); }
SkXfermode* readXfermode() { return this->readFlattenable<SkXfermode>(); }
/**
* Like readFlattenable() but explicitly just skips the data that was written for the
* flattenable (or the sentinel that there wasn't one).
*/
virtual void skipFlattenable();
// binary data and arrays
virtual bool readByteArray(void* value, size_t size);
@ -130,7 +149,12 @@ public:
// helpers to get info about arrays and binary data
virtual uint32_t getArrayCount();
virtual void readBitmap(SkBitmap* bitmap);
/**
* Returns false if the bitmap could not be completely read. In that case, it will be set
* to have width/height, but no pixels.
*/
bool readBitmap(SkBitmap* bitmap);
virtual SkTypeface* readTypeface();
void setBitmapStorage(SkBitmapHeapReader* bitmapStorage) {
@ -184,6 +208,7 @@ private:
bool readArray(void* value, size_t size, size_t elementSize);
uint32_t fFlags;
int fVersion;
void* fMemoryPtr;

View File

@ -33,14 +33,14 @@ public:
fStop = (const char*)data + size;
}
uint32_t size() const { return SkToU32(fStop - fBase); }
uint32_t offset() const { return SkToU32(fCurr - fBase); }
size_t size() const { return fStop - fBase; }
size_t offset() const { return fCurr - fBase; }
bool eof() const { return fCurr >= fStop; }
const void* base() const { return fBase; }
const void* peek() const { return fCurr; }
uint32_t available() const { return SkToU32(fStop - fCurr); }
bool isAvailable(uint32_t size) const { return fCurr + size <= fStop; }
size_t available() const { return fStop - fCurr; }
bool isAvailable(size_t size) const { return size <= this->available(); }
void rewind() { fCurr = fBase; }

View File

@ -157,6 +157,20 @@ struct SK_API SkIRect {
fRight = fBottom = SK_MinS32;
}
/**
* Return a new IRect, built as an offset of this rect.
*/
SkIRect makeOffset(int dx, int dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
}
/**
* Return a new IRect, built as an inset of this rect.
*/
SkIRect makeInset(int dx, int dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
@ -577,6 +591,20 @@ struct SK_API SkRect {
fRight = fBottom = SK_ScalarMin;
}
/**
* Return a new Rect, built as an offset of this rect.
*/
SkRect makeOffset(SkScalar dx, SkScalar dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy);
}
/**
* Return a new Rect, built as an inset of this rect.
*/
SkRect makeInset(SkScalar dx, SkScalar dy) const {
return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy);
}
/** Offset set the rectangle by adding dx to its left and right,
and adding dy to its top and bottom.
*/
@ -731,6 +759,24 @@ struct SK_API SkRect {
SkScalarRoundToInt(fRight), SkScalarRoundToInt(fBottom));
}
/**
* Variant of round() that explicitly performs the rounding step (i.e. floor(x + 0.5)) using
* double instead of SkScalar (float). It does this by calling SkDScalarRoundToInt(), which
* may be slower than calling SkScalarRountToInt(), but gives slightly more accurate results.
*
* e.g.
* SkScalar x = 0.49999997f;
* int ix = SkScalarRoundToInt(x);
* SkASSERT(0 == ix); // <--- fails
* ix = SkDScalarRoundToInt(x);
* SkASSERT(0 == ix); // <--- succeeds
*/
void dround(SkIRect* dst) const {
SkASSERT(dst);
dst->set(SkDScalarRoundToInt(fLeft), SkDScalarRoundToInt(fTop),
SkDScalarRoundToInt(fRight), SkDScalarRoundToInt(fBottom));
}
/**
* Set the dst rectangle by rounding "out" this rectangle, choosing the
* SkScalarFloor of top and left, and the SkScalarCeil of right and bottom.
@ -787,6 +833,17 @@ struct SK_API SkRect {
* cast-safe way to treat the rect as an array of (4) SkScalars.
*/
const SkScalar* asScalars() const { return &fLeft; }
#ifdef SK_DEVELOPER
/**
* Dumps the rect using SkDebugf. This is intended for Skia development debugging. Don't
* rely on the existence of this function or the formatting of its output.
*/
void dump() const {
SkDebugf("{ l: %f, t: %f, r: %f, b: %f }", fLeft, fTop, fRight, fBottom);
}
#endif
};
#endif

View File

@ -25,7 +25,7 @@
destructor to be called explicitly (or via the object going out of scope on
the stack or calling delete) if getRefCnt() > 1.
*/
class SK_API SkRefCntBase : public SkNoncopyable {
class SK_API SkRefCntBase : SkNoncopyable {
public:
SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase)
@ -37,7 +37,7 @@ public:
*/
virtual ~SkRefCntBase() {
#ifdef SK_DEBUG
SkASSERT(fRefCnt == 1);
SkASSERTF(fRefCnt == 1, "fRefCnt was %d", fRefCnt);
fRefCnt = 0; // illegal value, to catch us if we reuse after delete
#endif
}
@ -113,7 +113,6 @@ private:
// The following friends are those which override internal_dispose()
// and conditionally call SkRefCnt::internal_dispose().
friend class GrTexture;
friend class SkWeakRefCnt;
mutable int32_t fRefCnt;
@ -248,45 +247,4 @@ public:
};
#define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref)
class SkAutoRef : SkNoncopyable {
public:
SkAutoRef(SkRefCnt* obj) : fObj(obj) { SkSafeRef(obj); }
~SkAutoRef() { SkSafeUnref(fObj); }
private:
SkRefCnt* fObj;
};
#define SkAutoRef(...) SK_REQUIRE_LOCAL_VAR(SkAutoRef)
/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to
a SkRefCnt (or subclass) object.
*/
template <typename T> class SkRefPtr {
public:
SkRefPtr() : fObj(NULL) {}
SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); }
SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); }
~SkRefPtr() { SkSafeUnref(fObj); }
SkRefPtr& operator=(const SkRefPtr& rp) {
SkRefCnt_SafeAssign(fObj, rp.fObj);
return *this;
}
SkRefPtr& operator=(T* obj) {
SkRefCnt_SafeAssign(fObj, obj);
return *this;
}
T* get() const { return fObj; }
T& operator*() const { return *fObj; }
T* operator->() const { return fObj; }
typedef T* SkRefPtr::*unspecified_bool_type;
operator unspecified_bool_type() const {
return fObj ? &SkRefPtr::fObj : NULL;
}
private:
T* fObj;
};
#endif

View File

@ -244,9 +244,13 @@ public:
kXOR_Op, //!< exclusive-or the two regions
/** subtract the first region from the op region */
kReverseDifference_Op,
kReplace_Op //!< replace the dst region with the op region
kReplace_Op, //!< replace the dst region with the op region
kLastOp = kReplace_Op
};
static const int kOpCnt = kLastOp + 1;
/**
* Set this region to the result of applying the Op to this region and the
* specified rectangle: this = (this op rect).

View File

@ -83,6 +83,26 @@ static inline bool SkScalarIsFinite(float x) {
#define SkScalarRoundToInt(x) sk_float_round2int(x)
#define SkScalarTruncToInt(x) static_cast<int>(x)
/**
* Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using
* double, to avoid possibly losing the low bit(s) of the answer before calling floor().
*
* This routine will likely be slower than SkScalarRoundToInt(), and should only be used when the
* extra precision is known to be valuable.
*
* In particular, this catches the following case:
* SkScalar x = 0.49999997;
* int ix = SkScalarRoundToInt(x);
* SkASSERT(0 == ix); // <--- fails
* ix = SkDScalarRoundToInt(x);
* SkASSERT(0 == ix); // <--- succeeds
*/
static inline int SkDScalarRoundToInt(SkScalar x) {
double xx = x;
xx += 0.5;
return (int)floor(xx);
}
/** Returns the absolute value of the specified SkScalar
*/
#define SkScalarAbs(x) sk_float_abs(x)

View File

@ -14,10 +14,13 @@
#include "SkMask.h"
#include "SkMatrix.h"
#include "SkPaint.h"
#include "GrColor.h"
class SkPath;
class SkPicture;
class SkXfermode;
class GrContext;
class GrEffectRef;
class GrEffect;
/** \class SkShader
*
@ -33,29 +36,24 @@ class SK_API SkShader : public SkFlattenable {
public:
SK_DECLARE_INST_COUNT(SkShader)
SkShader();
SkShader(const SkMatrix* localMatrix = NULL);
virtual ~SkShader();
/**
* Returns true if the local matrix is not an identity matrix.
*/
bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
/**
* Returns the local matrix.
*
* FIXME: This can be incorrect for a Shader with its own local matrix
* that is also wrapped via CreateLocalMatrixShader.
*/
const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
/**
* Set the shader's local matrix.
* @param localM The shader's new local matrix.
* Returns true if the local matrix is not an identity matrix.
*
* FIXME: This can be incorrect for a Shader with its own local matrix
* that is also wrapped via CreateLocalMatrixShader.
*/
void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
/**
* Reset the shader's local matrix to identity.
*/
void resetLocalMatrix() { fLocalMatrix.reset(); }
bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
enum TileMode {
/** replicate the edge color if the shader draws outside of its
@ -95,7 +93,7 @@ public:
*/
kIntrinsicly16_Flag = 0x04,
/** set (after setContext) if the spans only vary in X (const in Y).
/** set if the spans only vary in X (const in Y).
e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
that varies from left-to-right. This flag specifies this for
shadeSpan().
@ -110,85 +108,121 @@ public:
kConstInY16_Flag = 0x10
};
/**
* Called sometimes before drawing with this shader. Return the type of
* alpha your shader will return. The default implementation returns 0.
* Your subclass should override if it can (even sometimes) report a
* non-zero value, since that will enable various blitters to perform
* faster.
*/
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.
* optimizations.
*/
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.
* ContextRec acts as a parameter bundle for creating Contexts.
*/
virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
struct ContextRec {
ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {}
ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
: fDevice(&device)
, fPaint(&paint)
, fMatrix(&matrix)
, fLocalMatrix(NULL) {}
const SkBitmap* fDevice; // the bitmap we are drawing into
const SkPaint* fPaint; // the current paint associated with the draw
const SkMatrix* fMatrix; // the current matrix in the canvas
const SkMatrix* fLocalMatrix; // optional local matrix
};
class Context : public ::SkNoncopyable {
public:
Context(const SkShader& shader, const ContextRec&);
virtual ~Context();
/**
* Called sometimes before drawing with this shader. Return the type of
* alpha your shader will return. The default implementation returns 0.
* Your subclass should override if it can (even sometimes) report a
* non-zero value, since that will enable various blitters to perform
* faster.
*/
virtual uint32_t getFlags() const { return 0; }
/**
* Return the alpha associated with the data returned by shadeSpan16(). If
* kHasSpan16_Flag is not set, this value is meaningless.
*/
virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
/**
* Called for each span of the object being drawn. Your subclass should
* set the appropriate colors (with premultiplied alpha) that correspond
* to the specified device coordinates.
*/
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
virtual ShadeProc asAShadeProc(void** ctx);
/**
* Called only for 16bit devices when getFlags() returns
* kOpaqueAlphaFlag | kHasSpan16_Flag
*/
virtual void shadeSpan16(int x, int y, uint16_t[], int count);
/**
* Similar to shadeSpan, but only returns the alpha-channel for a span.
* The default implementation calls shadeSpan() and then extracts the alpha
* values from the returned colors.
*/
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
/**
* Helper function that returns true if this shader's shadeSpan16() method
* can be called.
*/
bool canCallShadeSpan16() {
return SkShader::CanCallShadeSpan16(this->getFlags());
}
protected:
// Reference to shader, so we don't have to dupe information.
const SkShader& fShader;
enum MatrixClass {
kLinear_MatrixClass, // no perspective
kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
// scanline
kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
};
static MatrixClass ComputeMatrixClass(const SkMatrix&);
uint8_t getPaintAlpha() const { return fPaintAlpha; }
const SkMatrix& getTotalInverse() const { return fTotalInverse; }
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
const SkMatrix& getCTM() const { return fCTM; }
private:
SkMatrix fCTM;
SkMatrix fTotalInverse;
uint8_t fPaintAlpha;
uint8_t fTotalInverseClass;
typedef SkNoncopyable INHERITED;
};
/**
* Called once before drawing, with the current paint and device matrix.
* Return true if your shader supports these parameters, or false if not.
* If false is returned, nothing will be drawn. If true is returned, then
* a balancing call to endContext() will be made before the next call to
* setContext.
* Create the actual object that does the shading.
* Size of storage must be >= contextSize.
*/
Context* createContext(const ContextRec&, void* storage) const;
/**
* Return the size of a Context returned by createContext.
*
* Subclasses should be sure to call their INHERITED::setContext() if they
* override this method.
* Override this if your subclass overrides createContext, to return the correct size of
* your subclass' context.
*/
virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
const SkMatrix& matrix);
/**
* Assuming setContext returned true, endContext() will be called when
* the draw using the shader has completed. It is an error for setContext
* to be called twice w/o an intervening call to endContext().
*
* Subclasses should be sure to call their INHERITED::endContext() if they
* override this method.
*/
virtual void endContext();
SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetContext); })
/**
* Called for each span of the object being drawn. Your subclass should
* set the appropriate colors (with premultiplied alpha) that correspond
* to the specified device coordinates.
*/
virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
virtual ShadeProc asAShadeProc(void** ctx);
/**
* Called only for 16bit devices when getFlags() returns
* kOpaqueAlphaFlag | kHasSpan16_Flag
*/
virtual void shadeSpan16(int x, int y, uint16_t[], int count);
/**
* Similar to shadeSpan, but only returns the alpha-channel for a span.
* The default implementation calls shadeSpan() and then extracts the alpha
* values from the returned colors.
*/
virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
/**
* Helper function that returns true if this shader's shadeSpan16() method
* can be called.
*/
bool canCallShadeSpan16() {
return SkShader::CanCallShadeSpan16(this->getFlags());
}
virtual size_t contextSize() const;
/**
* Helper to check the flags to know if it is legal to call shadeSpan16()
@ -317,17 +351,57 @@ public:
virtual GradientType asAGradient(GradientInfo* info) const;
/**
* If the shader subclass has a GrEffect implementation, this resturns the effect to install.
* The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
* The output color should be the computed SkShader premul color modulated by the incoming
* color. The GrContext may be used by the effect to create textures. The GPU device does not
* call setContext. Instead we pass the SkPaint here in case the shader needs paint info.
* If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
* fill it out with info about the shader.
*
* These are bare pointers; the ownership and reference count are unchanged.
*/
virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const;
struct ComposeRec {
const SkShader* fShaderA;
const SkShader* fShaderB;
const SkXfermode* fMode;
};
virtual bool asACompose(ComposeRec* rec) const { return false; }
/**
* Returns true if the shader subclass succeeds in creating an effect or if none is required.
* False is returned if it fails or if there is not an implementation of this method in the
* shader subclass.
*
* On success an implementation of this method must inspect the SkPaint and set paintColor to
* the color the effect expects as its input color. If the SkShader wishes to emit a solid
* color then it should set paintColor to that color and not create an effect. Note that
* GrColor is always premul. The common patterns are to convert paint's SkColor to GrColor or
* to extract paint's alpha and replicate it to all channels in paintColor. Upon failure
* paintColor should not be modified. It is not recommended to specialize the effect to
* the paint's color as then many GPU shaders may be generated.
*
* The GrContext may be used by the effect to create textures. The GPU device does not
* call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
*/
virtual bool asNewEffect(GrContext* context, const SkPaint& paint,
const SkMatrix* localMatrixOrNull, GrColor* paintColor,
GrEffect** effect) const;
#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
/**
* If the shader is a custom shader which has data the caller might want, call this function
* to get that data.
*/
virtual bool asACustomShader(void** customData) const { return false; }
#endif
//////////////////////////////////////////////////////////////////////////
// Factory methods for stock shaders
/**
* Call this to create a new "empty" shader, that will not draw anything.
*/
static SkShader* CreateEmptyShader();
/** Call this to create a new shader that will draw with the specified bitmap.
*
* If the bitmap cannot be used (e.g. has no pixels, or its dimensions
@ -343,32 +417,61 @@ public:
* @return Returns a new shader object. Note: this function never returns null.
*/
static SkShader* CreateBitmapShader(const SkBitmap& src,
TileMode tmx, TileMode tmy);
TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix = NULL);
/** Call this to create a new shader that will draw with the specified picture.
*
* @param src The picture to use inside the shader (if not NULL, its ref count
* is incremented). The SkPicture must not be changed after
* successfully creating a picture shader.
* FIXME: src cannot be const due to SkCanvas::drawPicture
* @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
* @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
* @return Returns a new shader object. Note: this function never returns null.
*/
static SkShader* CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix = NULL);
/**
* Return a shader that will apply the specified localMatrix to the proxy shader.
* The specified matrix will be applied before any matrix associated with the proxy.
*
* Note: ownership of the proxy is not transferred (though a ref is taken).
*/
static SkShader* CreateLocalMatrixShader(SkShader* proxy, const SkMatrix& localMatrix);
/**
* If this shader can be represented by another shader + a localMatrix, return that shader
* and, if not NULL, the localMatrix. If not, return NULL and ignore the localMatrix parameter.
*
* Note: the returned shader (if not NULL) will have been ref'd, and it is the responsibility
* of the caller to balance that with unref() when they are done.
*/
virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const;
SK_TO_STRING_VIRT()
SK_DEFINE_FLATTENABLE_TYPE(SkShader)
protected:
enum MatrixClass {
kLinear_MatrixClass, // no perspective
kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each scanline
kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
};
static MatrixClass ComputeMatrixClass(const SkMatrix&);
// These can be called by your subclass after setContext() has been called
uint8_t getPaintAlpha() const { return fPaintAlpha; }
const SkMatrix& getTotalInverse() const { return fTotalInverse; }
MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
SkShader(SkReadBuffer& );
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
/**
* Your subclass must also override contextSize() if it overrides onCreateContext().
* Base class impl returns NULL.
*/
virtual Context* onCreateContext(const ContextRec&, void* storage) const;
private:
SkMatrix fLocalMatrix;
SkMatrix fTotalInverse;
uint8_t fPaintAlpha;
uint8_t fTotalInverseClass;
SkDEBUGCODE(SkBool8 fInSetContext;)
// This is essentially const, but not officially so it can be modified in
// constructors.
SkMatrix fLocalMatrix;
// So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor.
friend class SkLocalMatrixShader;
typedef SkFlattenable INHERITED;
};

View File

@ -21,6 +21,7 @@ public:
SkStrokeRec(InitStyle style);
SkStrokeRec(const SkStrokeRec&);
SkStrokeRec(const SkPaint&, SkPaint::Style);
explicit SkStrokeRec(const SkPaint&);
enum Style {
@ -29,6 +30,9 @@ public:
kStroke_Style,
kStrokeAndFill_Style
};
enum {
kStyleCount = kStrokeAndFill_Style + 1
};
Style getStyle() const;
SkScalar getWidth() const { return fWidth; }
@ -90,6 +94,9 @@ public:
}
private:
void init(const SkPaint& paint, SkPaint::Style style);
SkScalar fWidth;
SkScalar fMiterLimit;
SkPaint::Cap fCap;

View File

@ -37,6 +37,14 @@ public:
*/
static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes);
/**
* The same as NewRasterDirect, but also accepts a call-back routine, which is invoked
* when the surface is deleted, and is passed the pixel memory and the specified context.
*/
static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes,
void (*releaseProc)(void* pixels, void* context),
void* context);
/**
* Return a new surface, with the memory for the pixels automatically
* allocated.
@ -56,22 +64,58 @@ public:
}
/**
* Return a new surface whose contents will be recorded into a picture.
* When this surface is drawn into another canvas, its contents will be
* "replayed" into that canvas.
* Text rendering modes that can be passed to NewRenderTarget*
*/
static SkSurface* NewPicture(int width, int height);
enum TextRenderMode {
/**
* This will use the standard text rendering method
*/
kStandard_TextRenderMode,
/**
* This will use signed distance fields for text rendering when possible
*/
kDistanceField_TextRenderMode,
};
enum RenderTargetFlags {
kNone_RenderTargetFlag = 0x0,
/*
* By default a RenderTarget-based surface will be cleared on creation.
* Pass in this flag to prevent the clear from happening.
*/
kDontClear_RenderTargetFlag = 0x01,
};
/**
* Return a new surface using the specified render target.
*/
static SkSurface* NewRenderTargetDirect(GrRenderTarget*);
static SkSurface* NewRenderTargetDirect(GrRenderTarget*,
TextRenderMode trm = kStandard_TextRenderMode,
RenderTargetFlags flags = kNone_RenderTargetFlag);
/**
* Return a new surface whose contents will be drawn to an offscreen
* render target, allocated by the surface.
*/
static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0);
static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
TextRenderMode trm = kStandard_TextRenderMode,
RenderTargetFlags flags = kNone_RenderTargetFlag);
/**
* Return a new surface whose contents will be drawn to an offscreen
* render target, allocated by the surface from the scratch texture pool
* managed by the GrContext. The scratch texture pool serves the purpose
* of retaining textures after they are no longer in use in order to
* re-use them later without having to re-allocate. Scratch textures
* should be used in cases where high turnover is expected. This allows,
* for example, the copy on write to recycle a texture from a recently
* released SkImage snapshot of the surface.
* Note: Scratch textures count against the GrContext's cached resource
* budget.
*/
static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0,
TextRenderMode trm = kStandard_TextRenderMode,
RenderTargetFlags flags = kNone_RenderTargetFlag);
int width() const { return fWidth; }
int height() const { return fHeight; }

View File

@ -16,6 +16,10 @@ template <typename T, bool MEM_COPY = false> class SkTArray;
namespace SkTArrayExt {
template<typename T>
inline void copy(SkTArray<T, true>* self, int dst, int src) {
memcpy(&self->fItemArray[dst], &self->fItemArray[src], sizeof(T));
}
template<typename T>
inline void copy(SkTArray<T, true>* self, const T* array) {
memcpy(self->fMemArray, array, self->fCount * sizeof(T));
@ -25,6 +29,10 @@ inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) {
memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T));
}
template<typename T>
inline void copy(SkTArray<T, false>* self, int dst, int src) {
SkNEW_PLACEMENT_ARGS(&self->fItemArray[dst], T, (self->fItemArray[src]));
}
template<typename T>
inline void copy(SkTArray<T, false>* self, const T* array) {
for (int i = 0; i < self->fCount; ++i) {
@ -45,7 +53,7 @@ template <typename T, bool MEM_COPY> void* operator new(size_t, SkTArray<T, MEM_
/** When MEM_COPY is true T will be bit copied when moved.
When MEM_COPY is false, T will be copy constructed / destructed.
In all cases T's constructor will be called on allocation,
In all cases T will be default-initialized on allocation,
and its destructor will be called from this object's destructor.
*/
template <typename T, bool MEM_COPY> class SkTArray {
@ -140,8 +148,17 @@ public:
int delta = count - fCount;
this->checkRealloc(delta);
fCount = count;
for (int i = 0; i < count; ++i) {
SkTArrayExt::copy(this, array);
SkTArrayExt::copy(this, array);
}
void removeShuffle(int n) {
SkASSERT(n < fCount);
int newCount = fCount - 1;
fCount = newCount;
fItemArray[n].~T();
if (n != newCount) {
SkTArrayExt::copy(this, n, newCount);
fItemArray[newCount].~T();
}
}
@ -156,7 +173,7 @@ public:
bool empty() const { return !fCount; }
/**
* Adds 1 new default-constructed T value and returns in by reference. Note
* Adds 1 new default-initialized T value and returns it by reference. Note
* the reference only remains valid until the next call that adds or removes
* elements.
*/
@ -176,9 +193,9 @@ public:
}
/**
* Allocates n more default T values, and returns the address of the start
* of that new range. Note: this address is only valid until the next API
* call made on the array that might add or remove elements.
* Allocates n more default-initialized T values, and returns the address of
* the start of that new range. Note: this address is only valid until the
* next API call made on the array that might add or remove elements.
*/
T* push_back_n(int n) {
SkASSERT(n >= 0);
@ -427,9 +444,11 @@ private:
friend void* operator new<T>(size_t, SkTArray*, int);
template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, int dst, int src);
template<typename X> friend void SkTArrayExt::copy(SkTArray<X, true>* that, const X*);
template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, true>* that, char*);
template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, int dst, int src);
template<typename X> friend void SkTArrayExt::copy(SkTArray<X, false>* that, const X*);
template<typename X> friend void SkTArrayExt::copyAndDelete(SkTArray<X, false>* that, char*);

View File

@ -1,4 +1,3 @@
/*
* Copyright 2006 The Android Open Source Project
*
@ -6,7 +5,6 @@
* found in the LICENSE file.
*/
#ifndef SkTDict_DEFINED
#define SkTDict_DEFINED
@ -18,32 +16,26 @@ template <typename T> class SkTDict : SkNoncopyable {
public:
SkTDict(size_t minStringAlloc) : fStrings(minStringAlloc) {}
void reset()
{
void reset() {
fArray.reset();
fStrings.reset();
}
int count() const { return fArray.count(); }
bool set(const char name[], const T& value)
{
bool set(const char name[], const T& value) {
return set(name, strlen(name), value);
}
bool set(const char name[], size_t len, const T& value)
{
bool set(const char name[], size_t len, const T& value) {
SkASSERT(name);
int index = this->find_index(name, len);
if (index >= 0)
{
if (index >= 0) {
fArray[index].fValue = value;
return false;
}
else
{
} else {
Pair* pair = fArray.insert(~index);
char* copy = (char*)fStrings.alloc(len + 1, SkChunkAlloc::kThrow_AllocFailType);
memcpy(copy, name, len);
@ -54,40 +46,36 @@ public:
}
}
bool find(const char name[]) const
{
bool find(const char name[]) const {
return this->find_index(name) >= 0;
}
bool find(const char name[], size_t len) const
{
bool find(const char name[], size_t len) const {
return this->find_index(name, len) >= 0;
}
bool find(const char name[], T* value) const
{
bool find(const char name[], T* value) const {
return find(name, strlen(name), value);
}
bool find(const char name[], size_t len, T* value) const
{
bool find(const char name[], size_t len, T* value) const {
int index = this->find_index(name, len);
if (index >= 0)
{
if (value)
if (index >= 0) {
if (value) {
*value = fArray[index].fValue;
}
return true;
}
return false;
}
bool findKey(T& value, const char** name) const
{
bool findKey(T& value, const char** name) const {
const Pair* end = fArray.end();
for (const Pair* pair = fArray.begin(); pair < end; pair++) {
if (pair->fValue != value)
if (pair->fValue != value) {
continue;
}
*name = pair->fName;
return true;
}
@ -99,12 +87,11 @@ public:
const char* fName;
T fValue;
friend int operator<(const Pair& a, const Pair& b)
{
friend int operator<(const Pair& a, const Pair& b) {
return strcmp(a.fName, b.fName);
}
friend int operator!=(const Pair& a, const Pair& b)
{
friend int operator!=(const Pair& a, const Pair& b) {
return strcmp(a.fName, b.fName);
}
};
@ -113,19 +100,18 @@ public:
public:
class Iter {
public:
Iter(const SkTDict<T>& dict)
{
Iter(const SkTDict<T>& dict) {
fIter = dict.fArray.begin();
fStop = dict.fArray.end();
}
const char* next(T* value)
{
const char* next(T* value) {
const char* name = NULL;
if (fIter < fStop)
{
if (fIter < fStop) {
name = fIter->fName;
if (value)
if (value) {
*value = fIter->fValue;
}
fIter += 1;
}
return name;
@ -139,20 +125,19 @@ private:
SkTDArray<Pair> fArray;
SkChunkAlloc fStrings;
int find_index(const char name[]) const
{
int find_index(const char name[]) const {
return find_index(name, strlen(name));
}
int find_index(const char name[], size_t len) const
{
int find_index(const char name[], size_t len) const {
SkASSERT(name);
int count = fArray.count();
int index = ~0;
if (count)
if (count) {
index = SkStrSearch(&fArray.begin()->fName, count, name, len, sizeof(Pair));
}
return index;
}
friend class Iter;

View File

@ -38,7 +38,7 @@ template <typename T> class SkPtrWrapper {
/**
* This class implements a templated internal doubly linked list data structure.
*/
template <class T> class SkTInternalLList : public SkNoncopyable {
template <class T> class SkTInternalLList : SkNoncopyable {
public:
SkTInternalLList()
: fHead(NULL)

View File

@ -11,7 +11,6 @@
#define SkTemplates_DEFINED
#include "SkTypes.h"
#include <limits>
#include <limits.h>
#include <new>
@ -66,15 +65,6 @@ template <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffs
);
}
/** SkTSetBit<N, T>::value is a T with the Nth bit set. */
template<unsigned N, typename T = uintmax_t> struct SkTSetBit {
static const T value = static_cast<T>(1) << N;
SK_COMPILE_ASSERT(sizeof(T)*CHAR_BIT > N, SkTSetBit_N_too_large);
SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, SkTSetBit_T_must_be_integer);
SK_COMPILE_ASSERT(!std::numeric_limits<T>::is_signed, SkTSetBit_T_must_be_unsigned);
SK_COMPILE_ASSERT(std::numeric_limits<T>::radix == 2, SkTSetBit_T_radix_must_be_2);
};
/** \class SkAutoTCallVProc
Call a function when this goes out of scope. The template uses two
@ -340,7 +330,7 @@ public:
/** Allocates space for 'count' Ts. */
explicit SkAutoTMalloc(size_t count) {
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
}
~SkAutoTMalloc() {
@ -355,7 +345,7 @@ public:
/** Resize the memory area pointed to by the current ptr without preserving contents. */
void reset(size_t count) {
sk_free(fPtr);
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW | SK_MALLOC_TEMP);
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
}
T* get() const { return fPtr; }

View File

@ -16,6 +16,7 @@
* No additional memory barrier is required; this must act as a compiler barrier.
*/
static int32_t sk_atomic_inc(int32_t* addr);
static int64_t sk_atomic_inc(int64_t* addr);
/** Atomically adds inc to the int referenced by addr and returns the previous value.
* No additional memory barrier is required; this must act as a compiler barrier.
@ -27,12 +28,6 @@ static int32_t sk_atomic_add(int32_t* addr, int32_t inc);
*/
static int32_t sk_atomic_dec(int32_t* addr);
/** Atomically adds one to the int referenced by addr iff the referenced int was not 0
* and returns the previous value.
* No additional memory barrier is required; this must act as a compiler barrier.
*/
static int32_t sk_atomic_conditional_inc(int32_t* addr);
/** Atomic compare and set.
* If *addr == before, set *addr to after and return true, otherwise return false.
* This must act as a release (SL/S) memory barrier and as a compiler barrier.
@ -51,12 +46,47 @@ static void sk_membar_acquire__after_atomic_conditional_inc();
#include SK_ATOMICS_PLATFORM_H
/** Atomically adds one to the int referenced by addr iff the referenced int was not 0
* and returns the previous value.
* No additional memory barrier is required; this must act as a compiler barrier.
*/
template<typename INT_TYPE> static inline INT_TYPE sk_atomic_conditional_inc(INT_TYPE* addr) {
INT_TYPE prev;
do {
prev = *addr;
if (0 == prev) {
break;
}
} while (!sk_atomic_cas(addr, prev, prev+1));
return prev;
}
// SK_BARRIERS_PLATFORM_H must provide implementations for the following declarations:
/** Prevent the compiler from reordering across this barrier. */
static void sk_compiler_barrier();
/** Read T*, with at least an acquire barrier.
*
* Only needs to be implemented for T which can be atomically read.
*/
template <typename T> T sk_acquire_load(T*);
/** Write T*, with at least a release barrier.
*
* Only needs to be implemented for T which can be atomically written.
*/
template <typename T> void sk_release_store(T*, T);
#include SK_BARRIERS_PLATFORM_H
/** SK_MUTEX_PLATFORM_H must provide the following (or equivalent) declarations.
class SkBaseMutex {
public:
void acquire();
void release();
void acquire(); // Block until this thread owns the mutex.
void release(); // Assuming this thread owns the mutex, release it.
void assertHeld(); // If SK_DEBUG, assert this thread owns the mutex.
};
class SkMutex : SkBaseMutex {
@ -66,7 +96,6 @@ public:
};
#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ...
#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = ...
*/
#include SK_MUTEX_PLATFORM_H
@ -100,6 +129,12 @@ public:
}
}
/** Assert that we're holding the mutex. */
void assertHeld() {
SkASSERT(fMutex);
fMutex->assertHeld();
}
private:
SkBaseMutex* fMutex;
};

View File

@ -1,56 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkTileGridPicture_DEFINED
#define SkTileGridPicture_DEFINED
#include "SkPicture.h"
#include "SkPoint.h"
#include "SkSize.h"
/**
* Subclass of SkPicture that override the behavior of the
* kOptimizeForClippedPlayback_RecordingFlag by creating an SkTileGrid
* structure rather than an R-Tree. The tile grid has lower recording
* and playback costs, but is less effective at eliminating extraneous
* primitives for arbitrary query rectangles. It is most effective for
* tiled playback when the tile structure is known at record time.
*/
class SK_API SkTileGridPicture : public SkPicture {
public:
struct TileGridInfo {
/** Tile placement interval */
SkISize fTileInterval;
/** Pixel coverage overlap between adjacent tiles */
SkISize fMargin;
/** Offset added to device-space bounding box positions to convert
* them to tile-grid space. This can be used to adjust the "phase"
* of the tile grid to match probable query rectangles that will be
* used to search into the tile grid. As long as the offset is smaller
* or equal to the margin, there is no need to extend the domain of
* the tile grid to prevent data loss.
*/
SkIPoint fOffset;
};
/**
* Constructor
* @param width recording canvas width in device pixels
* @param height recording canvas height in device pixels
* @param info description of the tiling layout
*/
SkTileGridPicture(int width, int height, const TileGridInfo& info);
virtual SkBBoxHierarchy* createBBoxHierarchy() const SK_OVERRIDE;
private:
int fXTileCount, fYTileCount;
TileGridInfo fInfo;
};
#endif

View File

@ -1,45 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkTrace_DEFINED
#define SkTrace_DEFINED
#ifdef SK_USER_TRACE_INCLUDE_FILE
/* If your system embeds skia and has complex event logging, in
src/config/SkUserConfig.h:
- define the three SK_TRACE_EVENT macros to map to your system's
equivalents,
- define the name of the include file in SK_USER_TRACE_INCLUDE_FILE
A trivial example is given in src/utils/SkDebugTrace.h.
All arguments are const char*. Skia typically passes the name of
the object and function (and sometimes region of interest within
the function) separated by double colons for 'event'.
SK_TRACE_EVENT1 and SK_TRACE_EVENT2 take one or two arbitrary
name-value pairs that you also want to log. SkStringPrintf() is useful
for formatting these values.
For example:
SK_TRACE_EVENT0("GrContext::createAndLockTexture");
SK_TRACE_EVENT1("GrDefaultPathRenderer::onDrawPath::renderPasses",
"verts", SkStringPrintf("%i", vert - base).c_str());
*/
#include SK_USER_TRACE_INCLUDE_FILE
#else
#define SK_TRACE_EVENT0(event)
#define SK_TRACE_EVENT1(event, name1, value1)
#define SK_TRACE_EVENT2(event, name1, value1, name2, value2)
#endif
#endif

View File

@ -339,7 +339,8 @@ private:
uint32_t glyphIDsCount = 0) const;
private:
static void create_default_typeface(Style style);
static SkTypeface* CreateDefault(int style); // SkLazyPtr requires an int, not a Style.
static void DeleteDefault(SkTypeface*);
SkFontID fUniqueID;
Style fStyle;

View File

@ -93,7 +93,7 @@ inline void operator delete(void* p) {
#endif
#ifdef SK_DEBUG
#define SkASSERT(cond) SK_DEBUGBREAK(cond)
#define SkASSERT(cond) SK_ALWAYSBREAK(cond)
#define SkDEBUGFAIL(message) SkASSERT(false && message)
#define SkDEBUGCODE(code) code
#define SkDECLAREPARAM(type, var) , type var
@ -113,6 +113,13 @@ inline void operator delete(void* p) {
#define SkAssertResult(cond) cond
#endif
#define SkFAIL(message) SK_ALWAYSBREAK(false && message)
// We want to evaluate cond only once, and inside the SkASSERT somewhere so we see its string form.
// So we use the comma operator to make an SkDebugf that always returns false: we'll evaluate cond,
// and if it's true the assert passes; if it's false, we'll print the message and the assert fails.
#define SkASSERTF(cond, fmt, ...) SkASSERT((cond) || (SkDebugf(fmt"\n", __VA_ARGS__), false))
#ifdef SK_DEVELOPER
#define SkDEVCODE(code) code
#else
@ -315,6 +322,13 @@ typedef uint32_t SkMSec;
*/
#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
/** The generation IDs in Skia reserve 0 has an invalid marker.
*/
#define SK_InvalidGenID 0
/** The unique IDs in Skia reserve 0 has an invalid marker.
*/
#define SK_InvalidUniqueID 0
/****************************************************************************
The rest of these only build with C++
*/
@ -486,7 +500,7 @@ private:
* the lifetime of the block, so the caller must not call sk_free() or delete
* on the block, unless detach() was called.
*/
class SkAutoMalloc : public SkNoncopyable {
class SkAutoMalloc : SkNoncopyable {
public:
explicit SkAutoMalloc(size_t size = 0) {
fPtr = size ? sk_malloc_throw(size) : NULL;

View File

@ -1,37 +0,0 @@
/*
* Copyright 2006 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 SkUnitMapper_DEFINED
#define SkUnitMapper_DEFINED
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkFlattenable.h"
class SkUnitMapper : public SkFlattenable {
public:
SK_DECLARE_INST_COUNT(SkUnitMapper)
SkUnitMapper() {}
/** Given a value in [0..0xFFFF], return a value in the same range.
*/
virtual uint16_t mapUnit16(uint16_t x) = 0;
SK_DEFINE_FLATTENABLE_TYPE(SkUnitMapper)
protected:
SkUnitMapper(SkReadBuffer& rb) : SkFlattenable(rb) {}
private:
typedef SkFlattenable INHERITED;
};
#endif

View File

@ -17,7 +17,7 @@
@param value The 16bit value to be copied into buffer
@param count The number of times value should be copied into the buffer.
*/
void sk_memset16_portable(uint16_t dst[], uint16_t value, int count);
void sk_memset16(uint16_t dst[], uint16_t value, int count);
typedef void (*SkMemset16Proc)(uint16_t dst[], uint16_t value, int count);
SkMemset16Proc SkMemset16GetPlatformProc();
@ -26,17 +26,18 @@ SkMemset16Proc SkMemset16GetPlatformProc();
@param value The 32bit value to be copied into buffer
@param count The number of times value should be copied into the buffer.
*/
void sk_memset32_portable(uint32_t dst[], uint32_t value, int count);
void sk_memset32(uint32_t dst[], uint32_t value, int count);
typedef void (*SkMemset32Proc)(uint32_t dst[], uint32_t value, int count);
SkMemset32Proc SkMemset32GetPlatformProc();
#ifndef sk_memset16
extern SkMemset16Proc sk_memset16;
#endif
#ifndef sk_memset32
extern SkMemset32Proc sk_memset32;
#endif
/** Similar to memcpy(), but it copies count 32bit values from src to dst.
@param dst The memory to have value copied into it
@param src The memory to have value copied from it
@param count The number of values should be copied.
*/
void sk_memcpy32(uint32_t dst[], const uint32_t src[], int count);
typedef void (*SkMemcpy32Proc)(uint32_t dst[], const uint32_t src[], int count);
SkMemcpy32Proc SkMemcpy32GetPlatformProc();
///////////////////////////////////////////////////////////////////////////////

View File

@ -58,7 +58,7 @@ public:
void write32(int32_t value);
void writeString(const char* value);
void writeEncodedString(const void* value, size_t byteLength, SkPaint::TextEncoding encoding);
void writeFunctionPtr(void* ptr) { this->writeByteArray(&ptr, sizeof(ptr)); }
void writeFunctionPtr(void* ptr) { fWriter.writePtr(ptr); }
void writeFlattenable(const SkFlattenable* flattenable);
void writeColor(const SkColor& color);

View File

@ -22,7 +22,7 @@
#include "SkTemplates.h"
#include "SkTypes.h"
class SkWriter32 : SkNoncopyable {
class SK_API SkWriter32 : SkNoncopyable {
public:
/**
* The caller can specify an initial block of storage, which the caller manages.

View File

@ -13,7 +13,7 @@
#include "SkFlattenable.h"
#include "SkColor.h"
class GrEffectRef;
class GrEffect;
class GrTexture;
class SkString;
@ -198,7 +198,7 @@ public:
fragment shader. If NULL, the effect should request access to destination color
(setWillReadDstColor()), and use that in the fragment shader (builder->dstColor()).
*/
virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background = NULL) const;
virtual bool asNewEffect(GrEffect** effect, GrTexture* background = NULL) const;
/** Returns true if the xfermode can be expressed as coeffs (src, dst), or as an effect
(effect). This helper calls the asCoeff() and asNewEffect() virtuals. If the xfermode is
@ -206,7 +206,7 @@ public:
simply test the return value. effect, src, and dst must all be NULL or all non-NULL.
*/
static bool AsNewEffectOrCoeff(SkXfermode*,
GrEffectRef** effect,
GrEffect** effect,
Coeff* src,
Coeff* dst,
GrTexture* background = NULL);
@ -216,7 +216,8 @@ public:
SK_DEFINE_FLATTENABLE_TYPE(SkXfermode)
protected:
SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
SkXfermode() {}
explicit SkXfermode(SkReadBuffer& rb) : SkFlattenable(rb) {}
/** The default implementation of xfer32/xfer16/xferA8 in turn call this
method, 1 color at a time (upscaled to a SkPMColor). The default
@ -228,68 +229,12 @@ protected:
*/
virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkXfermode() {}
private:
enum {
kModeCount = kLastMode + 1
};
friend class SkGraphics;
static void Term();
typedef SkFlattenable INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
/** \class SkProcXfermode
SkProcXfermode is a xfermode that applies the specified proc to its colors.
This class is not exported to java.
*/
class SkProcXfermode : public SkXfermode {
public:
static SkProcXfermode* Create(SkXfermodeProc proc) {
return SkNEW_ARGS(SkProcXfermode, (proc));
}
// overrides from SkXfermode
virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
const SkAlpha aa[]) const SK_OVERRIDE;
virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count,
const SkAlpha aa[]) const SK_OVERRIDE;
virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count,
const SkAlpha aa[]) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode)
protected:
SkProcXfermode(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
// allow subclasses to update this after we unflatten
void setProc(SkXfermodeProc proc) {
fProc = proc;
}
SkXfermodeProc getProc() const {
return fProc;
}
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {}
private:
SkXfermodeProc fProc;
typedef SkXfermode INHERITED;
};
#endif

View File

@ -141,11 +141,6 @@ protected:
int x, int y,
const SkPaint& paint) SK_OVERRIDE;
virtual bool onReadPixels(const SkBitmap& bitmap,
int x,
int y,
SkCanvas::Config8888) SK_OVERRIDE;
virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE;
private:

View File

@ -63,18 +63,14 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath1DPathEffect)
protected:
SkPath1DPathEffect(SkReadBuffer& buffer);
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
explicit SkPath1DPathEffect(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
// overrides from Sk1DPathEffect
virtual SkScalar begin(SkScalar contourLength) const SK_OVERRIDE;
virtual SkScalar next(SkPath*, SkScalar, SkPathMeasure&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style);
private:
SkPath fPath; // copied from constructor
SkScalar fAdvance; // copied from constructor

View File

@ -14,14 +14,9 @@
class SK_API Sk2DPathEffect : public SkPathEffect {
public:
static Sk2DPathEffect* Create(const SkMatrix& mat) {
return SkNEW_ARGS(Sk2DPathEffect, (mat));
}
virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
virtual bool filterPath(SkPath*, const SkPath&,
SkStrokeRec*, const SkRect*) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk2DPathEffect)
SK_DECLARE_UNFLATTENABLE_OBJECT()
protected:
/** New virtual, to be overridden by subclasses.
@ -43,14 +38,10 @@ protected:
const SkMatrix& getMatrix() const { return fMatrix; }
// protected so that subclasses can call this during unflattening
Sk2DPathEffect(SkReadBuffer&);
explicit Sk2DPathEffect(const SkMatrix& mat);
explicit Sk2DPathEffect(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
Sk2DPathEffect(const SkMatrix& mat);
private:
SkMatrix fMatrix, fInverse;
bool fMatrixIsInvertible;
@ -75,17 +66,13 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLine2DPathEffect)
protected:
virtual void nextSpan(int u, int v, int ucount, SkPath*) const SK_OVERRIDE;
SkLine2DPathEffect(SkReadBuffer&);
SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
: Sk2DPathEffect(matrix), fWidth(width) {}
explicit SkLine2DPathEffect(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix)
: Sk2DPathEffect(matrix), fWidth(width) {}
virtual void nextSpan(int u, int v, int ucount, SkPath*) const SK_OVERRIDE;
private:
SkScalar fWidth;
@ -106,16 +93,12 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath2DPathEffect)
protected:
SkPath2DPathEffect(SkReadBuffer& buffer);
SkPath2DPathEffect(const SkMatrix&, const SkPath&);
explicit SkPath2DPathEffect(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual void next(const SkPoint&, int u, int v, SkPath*) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkPath2DPathEffect(const SkMatrix&, const SkPath&);
private:
SkPath fPath;

View File

@ -20,7 +20,8 @@ public:
* The 0,0 point of the region corresponds to the upper left corner of the
* source image.
*/
static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold, SkScalar outerThreshold);
static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold,
SkScalar outerThreshold, SkImageFilter* input = NULL);
};
#endif

View File

@ -26,7 +26,8 @@ public:
* k1=k2=k4=0, k3=1.0 results in returning the dst
*/
static SkXfermode* Create(SkScalar k1, SkScalar k2,
SkScalar k3, SkScalar k4);
SkScalar k3, SkScalar k4,
bool enforcePMColor = true);
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP();

View File

@ -53,13 +53,9 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAvoidXfermode)
protected:
SkAvoidXfermode(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode);
explicit SkAvoidXfermode(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
SkColor fOpColor;

View File

@ -1,56 +0,0 @@
/*
* Copyright 2013 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 SkBicubicImageFilter_DEFINED
#define SkBicubicImageFilter_DEFINED
#include "SkImageFilter.h"
#include "SkScalar.h"
#include "SkSize.h"
#include "SkPoint.h"
/*! \class SkBicubicImageFilter
Bicubic resampling image filter. This filter does a 16-tap bicubic
filter using the given matrix.
*/
class SK_API SkBicubicImageFilter : public SkImageFilter {
public:
virtual ~SkBicubicImageFilter();
static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL);
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter)
protected:
/** Construct a (scaling-only) bicubic resampling image filter.
@param scale How much to scale the image.
@param coefficients The 16 coefficients of the bicubic matrix.
@param input The input image filter. If NULL, the src bitmap
passed to filterImage() is used instead.
*/
SkBicubicImageFilter(const SkSize& scale, const SkScalar coefficients[16],
SkImageFilter* input = NULL);
SkBicubicImageFilter(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
#if SK_SUPPORT_GPU
virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
#endif
private:
SkSize fScale;
SkScalar fCoefficients[16];
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -25,18 +25,15 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource)
protected:
explicit SkBitmapSource(const SkBitmap& bitmap);
SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
explicit SkBitmapSource(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
explicit SkBitmapSource(const SkBitmap& bitmap);
SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
private:
SkBitmap fBitmap;
SkRect fSrcRect, fDstRect;

View File

@ -35,12 +35,11 @@ public:
kAll_BlurFlag = 0x07
};
SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
uint32_t flags = kNone_BlurFlag);
static SkBlurDrawLooper* Create(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
uint32_t flags = kNone_BlurFlag) {
return SkNEW_ARGS(SkBlurDrawLooper, (color, sigma, dx, dy, flags));
}
// SK_ATTR_DEPRECATED("use sigma version")
SkBlurDrawLooper(SkScalar radius, SkScalar dx, SkScalar dy, SkColor color,
uint32_t flags = kNone_BlurFlag);
virtual ~SkBlurDrawLooper();
virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE;
@ -51,13 +50,18 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurDrawLooper)
protected:
SkBlurDrawLooper(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
uint32_t flags);
SkBlurDrawLooper(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual bool asABlurShadow(BlurShadowRec*) const SK_OVERRIDE;
private:
SkMaskFilter* fBlur;
SkColorFilter* fColorFilter;
SkScalar fDx, fDy;
SkScalar fDx, fDy, fSigma;
SkColor fBlurColor;
uint32_t fBlurFlags;
@ -79,6 +83,7 @@ private:
};
void init(SkScalar sigma, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags);
void initEffects();
typedef SkDrawLooper INHERITED;
};

View File

@ -25,6 +25,10 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
protected:
SkBlurImageFilter(SkScalar sigmaX,
SkScalar sigmaY,
SkImageFilter* input,
const CropRect* cropRect);
explicit SkBlurImageFilter(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
@ -37,14 +41,6 @@ protected:
virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkBlurImageFilter(SkScalar sigmaX,
SkScalar sigmaY,
SkImageFilter* input = NULL,
const CropRect* cropRect = NULL);
private:
SkSize fSigma;
typedef SkImageFilter INHERITED;

View File

@ -11,17 +11,15 @@
// we include this since our callers will need to at least be able to ref/unref
#include "SkMaskFilter.h"
#include "SkScalar.h"
#include "SkBlurTypes.h"
class SK_API SkBlurMaskFilter {
public:
enum BlurStyle {
kNormal_BlurStyle, //!< fuzzy inside and outside
kSolid_BlurStyle, //!< solid inside, fuzzy outside
kOuter_BlurStyle, //!< nothing inside, fuzzy outside
kInner_BlurStyle, //!< fuzzy inside, nothing outside
kBlurStyleCount
};
/**
* If radius > 0, return the corresponding sigma, else return 0. Use this to convert from the
* (legacy) idea of specify the blur "radius" to the standard notion of specifying its sigma.
*/
static SkScalar ConvertRadiusToSigma(SkScalar radius);
enum BlurFlags {
kNone_BlurFlag = 0x00,
@ -33,18 +31,13 @@ public:
kAll_BlurFlag = 0x03
};
SK_ATTR_DEPRECATED("use sigma version")
static SkMaskFilter* Create(SkScalar radius, BlurStyle style,
uint32_t flags = kNone_BlurFlag);
/** Create a blur maskfilter.
@param style The BlurStyle to use
@param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
@param flags Flags to use - defaults to none
@return The new blur maskfilter
*/
static SkMaskFilter* Create(BlurStyle style, SkScalar sigma,
uint32_t flags = kNone_BlurFlag);
* @param style The SkBlurStyle to use
* @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0.
* @param flags Flags to use - defaults to none
* @return The new blur maskfilter
*/
static SkMaskFilter* Create(SkBlurStyle style, SkScalar sigma, uint32_t flags = kNone_BlurFlag);
/** Create an emboss maskfilter
@param blurSigma standard deviation of the Gaussian blur to apply

View File

@ -33,7 +33,7 @@ protected:
private:
SkColorFilterImageFilter(SkColorFilter* cf,
SkImageFilter* input,
const CropRect* cropRect = NULL);
const CropRect* cropRect);
SkColorFilter* fColorFilter;
typedef SkImageFilter INHERITED;

View File

@ -26,7 +26,7 @@ public:
virtual uint32_t getFlags() const SK_OVERRIDE;
virtual bool asColorMatrix(SkScalar matrix[20]) const SK_OVERRIDE;
#if SK_SUPPORT_GPU
virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE;
virtual GrEffect* asNewEffect(GrContext*) const SK_OVERRIDE;
#endif
struct State {
@ -39,14 +39,10 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorMatrixFilter)
protected:
SkColorMatrixFilter(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
explicit SkColorMatrixFilter(const SkColorMatrix&);
SkColorMatrixFilter(const SkScalar array[20]);
explicit SkColorMatrixFilter(const SkScalar array[20]);
explicit SkColorMatrixFilter(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
SkColorMatrix fMatrix;

View File

@ -15,23 +15,20 @@ public:
virtual ~SkComposeImageFilter();
static SkComposeImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) {
return SkNEW_ARGS(SkComposeImageFilter, (outer, inner));
SkImageFilter* inputs[2] = { outer, inner };
return SkNEW_ARGS(SkComposeImageFilter, (inputs));
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter)
protected:
explicit SkComposeImageFilter(SkImageFilter* inputs[2]) : INHERITED(2, inputs) {}
explicit SkComposeImageFilter(SkReadBuffer& buffer);
virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {}
private:
typedef SkImageFilter INHERITED;
};

View File

@ -31,14 +31,10 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkCornerPathEffect)
protected:
SkCornerPathEffect(SkReadBuffer&);
explicit SkCornerPathEffect(SkScalar radius);
explicit SkCornerPathEffect(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkCornerPathEffect(SkScalar radius);
private:
SkScalar fRadius;

View File

@ -37,8 +37,8 @@ public:
Note: only affects stroked paths.
*/
static SkDashPathEffect* Create(const SkScalar intervals[], int count,
SkScalar phase, bool scaleToFit = false) {
return SkNEW_ARGS(SkDashPathEffect, (intervals, count, phase, scaleToFit));
SkScalar phase) {
return SkNEW_ARGS(SkDashPathEffect, (intervals, count, phase));
}
virtual ~SkDashPathEffect();
@ -49,28 +49,25 @@ public:
const SkStrokeRec&, const SkMatrix&,
const SkRect*) const SK_OVERRIDE;
virtual DashType asADash(DashInfo* info) const SK_OVERRIDE;
virtual Factory getFactory() const SK_OVERRIDE;
static SkFlattenable* CreateProc(SkReadBuffer&);
protected:
SkDashPathEffect(SkReadBuffer&);
SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase);
explicit SkDashPathEffect(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase,
bool scaleToFit = false);
private:
SkScalar* fIntervals;
int32_t fCount;
SkScalar fPhase;
// computed from phase
SkScalar fInitialDashLength;
int32_t fInitialDashIndex;
SkScalar fIntervalLength;
bool fScaleToFit;
typedef SkPathEffect INHERITED;
};

View File

@ -19,9 +19,21 @@ public:
/** Break the path into segments of segLength length, and randomly move the endpoints
away from the original path by a maximum of deviation.
Note: works on filled or framed paths
@param seedAssist This is a caller-supplied seedAssist that modifies
the seed value that is used to randomize the path
segments' endpoints. If not supplied it defaults to 0,
in which case filtering a path multiple times will
result in the same set of segments (this is useful for
testing). If a caller does not want this behaviour
they can pass in a different seedAssist to get a
different set of path segments.
*/
static SkDiscretePathEffect* Create(SkScalar segLength, SkScalar deviation) {
return SkNEW_ARGS(SkDiscretePathEffect, (segLength, deviation));
static SkDiscretePathEffect* Create(SkScalar segLength,
SkScalar deviation,
uint32_t seedAssist=0) {
return SkNEW_ARGS(SkDiscretePathEffect,
(segLength, deviation, seedAssist));
}
virtual bool filterPath(SkPath* dst, const SkPath& src,
@ -30,17 +42,18 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiscretePathEffect)
protected:
SkDiscretePathEffect(SkReadBuffer&);
SkDiscretePathEffect(SkScalar segLength,
SkScalar deviation,
uint32_t seedAssist);
explicit SkDiscretePathEffect(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
private:
SkScalar fSegLength, fPerterb;
/* Caller-supplied 32 bit seed assist */
uint32_t fSeedAssist;
typedef SkPathEffect INHERITED;
};

View File

@ -28,8 +28,9 @@ public:
SkScalar scale, SkImageFilter* displacement,
SkImageFilter* color = NULL,
const CropRect* cropRect = NULL) {
SkImageFilter* inputs[2] = { displacement, color };
return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale,
displacement, color, cropRect));
inputs, cropRect));
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
@ -51,17 +52,12 @@ public:
#endif
protected:
explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkDisplacementMapEffect(ChannelSelectorType xChannelSelector,
ChannelSelectorType yChannelSelector,
SkScalar scale, SkImageFilter* displacement,
SkImageFilter* color = NULL,
const CropRect* cropRect = NULL);
SkScalar scale, SkImageFilter* inputs[2],
const CropRect* cropRect);
explicit SkDisplacementMapEffect(SkReadBuffer& buffer);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
ChannelSelectorType fXChannelSelector;

View File

@ -11,10 +11,6 @@
class SK_API SkDropShadowImageFilter : public SkImageFilter {
public:
static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy, SkScalar sigma,
SkColor color, SkImageFilter* input = NULL) {
return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigma, color, input));
}
static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy,
SkScalar sigmaX, SkScalar sigmaY, SkColor color,
SkImageFilter* input = NULL,
@ -26,20 +22,14 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
protected:
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
SkImageFilter* input, const CropRect* cropRect);
explicit SkDropShadowImageFilter(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
virtual bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE;
virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
SkIRect* dst) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor,
SkImageFilter* input = NULL);
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,
SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
private:
SkScalar fDx, fDy, fSigmaX, fSigmaY;
SkColor fColor;

View File

@ -23,9 +23,7 @@ public:
uint8_t fSpecular; // exponent, 4.4 right now
};
static SkEmbossMaskFilter* Create(SkScalar blurSigma, const Light& light) {
return SkNEW_ARGS(SkEmbossMaskFilter, (blurSigma, light));
}
static SkEmbossMaskFilter* Create(SkScalar blurSigma, const Light& light);
// overrides from SkMaskFilter
// This method is not exported to java.
@ -38,13 +36,9 @@ public:
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmbossMaskFilter)
protected:
SkEmbossMaskFilter(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkEmbossMaskFilter(SkScalar blurSigma, const Light& light);
explicit SkEmbossMaskFilter(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
Light fLight;

View File

@ -10,7 +10,7 @@
#include "SkShader.h"
class SkUnitMapper;
#define SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
/** \class SkGradientShader
@ -43,13 +43,26 @@ public:
intermediate values must be strictly increasing.
@param count Must be >=2. The number of colors (and pos if not NULL) entries.
@param mode The tiling mode
@param mapper May be NULL. Callback to modify the spread of the colors.
*/
static SkShader* CreateLinear(const SkPoint pts[2],
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode,
SkUnitMapper* mapper = NULL,
uint32_t flags = 0);
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateLinear(const SkPoint pts[2],
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode) {
return CreateLinear(pts, colors, pos, count, mode, 0, NULL);
}
#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
static SkShader* CreateLinear(const SkPoint pts[2],
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode, void* ignored,
uint32_t flags, const SkMatrix* localMatrix) {
return CreateLinear(pts, colors, pos, count, mode, flags, localMatrix);
}
#endif
/** Returns a shader that generates a radial gradient given the center and radius.
<p />
@ -66,13 +79,26 @@ public:
intermediate values must be strictly increasing.
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
@param mode The tiling mode
@param mapper May be NULL. Callback to modify the spread of the colors.
*/
static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode,
SkUnitMapper* mapper = NULL,
uint32_t flags = 0);
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode) {
return CreateRadial(center, radius, colors, pos, count, mode, 0, NULL);
}
#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
static SkShader* CreateRadial(const SkPoint& center, SkScalar radius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode, void* ignored,
uint32_t flags, const SkMatrix* localMatrix) {
return CreateRadial(center, radius, colors, pos, count, mode, flags, localMatrix);
}
#endif
/** Returns a shader that generates a radial gradient given the start position, start radius, end position and end radius.
<p />
@ -92,17 +118,31 @@ public:
intermediate values must be strictly increasing.
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
@param mode The tiling mode
@param mapper May be NULL. Callback to modify the spread of the colors.
*/
static SkShader* CreateTwoPointRadial(const SkPoint& start,
SkScalar startRadius,
const SkPoint& end,
SkScalar endRadius,
const SkColor colors[],
const SkScalar pos[], int count,
static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode,
SkUnitMapper* mapper = NULL,
uint32_t flags = 0);
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode) {
return CreateTwoPointRadial(start, startRadius, end, endRadius, colors, pos, count, mode,
0, NULL);
}
#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
static SkShader* CreateTwoPointRadial(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode, void* ignored,
uint32_t flags, const SkMatrix* localMatrix) {
return CreateTwoPointRadial(start, startRadius, end, endRadius, colors, pos, count, mode,
flags, localMatrix);
}
#endif
/**
* Returns a shader that generates a conical gradient given two circles, or
@ -110,15 +150,30 @@ public:
* two circles according to the following HTML spec.
* http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient
*/
static SkShader* CreateTwoPointConical(const SkPoint& start,
SkScalar startRadius,
const SkPoint& end,
SkScalar endRadius,
const SkColor colors[],
const SkScalar pos[], int count,
static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode,
SkUnitMapper* mapper = NULL,
uint32_t flags = 0);
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode) {
return CreateTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode,
0, NULL);
}
#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
static SkShader* CreateTwoPointConical(const SkPoint& start, SkScalar startRadius,
const SkPoint& end, SkScalar endRadius,
const SkColor colors[], const SkScalar pos[], int count,
SkShader::TileMode mode, void* ignored,
uint32_t flags, const SkMatrix* localMatrix) {
return CreateTwoPointConical(start, startRadius, end, endRadius, colors, pos, count, mode,
flags, localMatrix);
}
#endif
/** Returns a shader that generates a sweep gradient given a center.
<p />
@ -134,12 +189,24 @@ public:
If this is not null, the values must begin with 0, end with 1.0, and
intermediate values must be strictly increasing.
@param count Must be >= 2. The number of colors (and pos if not NULL) entries
@param mapper May be NULL. Callback to modify the spread of the colors.
*/
static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
const SkColor colors[], const SkScalar pos[],
int count, SkUnitMapper* mapper = NULL,
uint32_t flags = 0);
const SkColor colors[], const SkScalar pos[], int count,
uint32_t flags, const SkMatrix* localMatrix);
static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
const SkColor colors[], const SkScalar pos[], int count) {
return CreateSweep(cx, cy, colors, pos, count, 0, NULL);
}
#ifdef SK_SUPPORT_LEGACY_GRADIENT_FACTORIES
static SkShader* CreateSweep(SkScalar cx, SkScalar cy,
const SkColor colors[], const SkScalar pos[], int count,
void* ignored,
uint32_t flags, const SkMatrix* localMatrix) {
return CreateSweep(cx, cy, colors, pos, count, flags, localMatrix);
}
#endif
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
};

View File

@ -1,69 +0,0 @@
/*
* Copyright 2008 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 SkKernel33MaskFilter_DEFINED
#define SkKernel33MaskFilter_DEFINED
#include "SkMaskFilter.h"
class SK_API SkKernel33ProcMaskFilter : public SkMaskFilter {
public:
virtual uint8_t computeValue(uint8_t* const* srcRows) const = 0;
virtual SkMask::Format getFormat() const SK_OVERRIDE;
virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&,
SkIPoint*) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
protected:
SkKernel33ProcMaskFilter(unsigned percent256 = 256)
: fPercent256(percent256) {}
SkKernel33ProcMaskFilter(SkReadBuffer& rb);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
int fPercent256;
typedef SkMaskFilter INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
class SK_API SkKernel33MaskFilter : public SkKernel33ProcMaskFilter {
public:
static SkKernel33MaskFilter* Create(const int coeff[3][3], int shift, int percent256 = 256) {
return SkNEW_ARGS(SkKernel33MaskFilter, (coeff, shift, percent256));
}
// override from SkKernel33ProcMaskFilter
virtual uint8_t computeValue(uint8_t* const* srcRows) const SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkKernel33MaskFilter)
protected:
#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS
public:
#endif
SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256)
: SkKernel33ProcMaskFilter(percent256) {
memcpy(fKernel, coeff, 9 * sizeof(int));
fShift = shift;
}
private:
int fKernel[3][3];
int fShift;
SkKernel33MaskFilter(SkReadBuffer& rb);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
typedef SkKernel33ProcMaskFilter INHERITED;
};
#endif

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