Bug 1246756 - part 3 - update Skia to m49 branch. r=jrmuizel

This commit is contained in:
Lee Salzman 2016-02-09 13:38:06 -05:00
parent 77e057ddea
commit 8f0be4e121
570 changed files with 15509 additions and 18891 deletions

View File

@ -22,5 +22,5 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1237983 - Investigate and remove the Bagheera Client implementation.
Bug 1246756 - Update Skia to m49 branch.

View File

@ -50,7 +50,25 @@ public:
/**
* Format of the encoded data.
*/
SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); }
SkEncodedFormat getEncodedFormat() const { return fCodec->getEncodedFormat(); }
/**
* @param requestedColorType Color type requested by the client
*
* If it is possible to decode to requestedColorType, this returns
* requestedColorType. Otherwise, this returns whichever color type
* is suggested by the codec as the best match for the encoded data.
*/
SkColorType computeOutputColorType(SkColorType requestedColorType);
/**
* @param requestedUnpremul Indicates if the client requested
* unpremultiplied output
*
* Returns the appropriate alpha type to decode to. If the image
* has alpha, the value of requestedUnpremul will be honored.
*/
SkAlphaType computeOutputAlphaType(bool requestedUnpremul);
/**
* Returns the dimensions of the scaled output image, for an input
@ -210,9 +228,9 @@ public:
protected:
SkAndroidCodec(const SkImageInfo&);
SkAndroidCodec(SkCodec*);
virtual SkEncodedFormat onGetEncodedFormat() const = 0;
SkCodec* codec() const { return fCodec.get(); }
virtual SkISize onGetSampledDimensions(int sampleSize) const = 0;
@ -226,5 +244,7 @@ private:
// This will always be a reference to the info that is contained by the
// embedded SkCodec.
const SkImageInfo& fInfo;
SkAutoTDelete<SkCodec> fCodec;
};
#endif // SkAndroidCodec_DEFINED

View File

@ -25,10 +25,35 @@ class SkSampler;
*/
class SkCodec : SkNoncopyable {
public:
/**
* Minimum number of bytes that must be buffered in SkStream input.
*
* An SkStream passed to NewFromStream must be able to use this many
* bytes to determine the image type. Then the same SkStream must be
* passed to the correct decoder to read from the beginning.
*
* This can be accomplished by implementing peek() to support peeking
* this many bytes, or by implementing rewind() to be able to rewind()
* after reading this many bytes.
*/
static size_t MinBufferedBytesNeeded();
/**
* If this stream represents an encoded image that we know how to decode,
* return an SkCodec that can decode it. Otherwise return NULL.
*
* As stated above, this call must be able to peek or read
* MinBufferedBytesNeeded to determine the correct format, and then start
* reading from the beginning. First it will attempt to peek, and it
* assumes that if less than MinBufferedBytesNeeded bytes (but more than
* zero) are returned, this is because the stream is shorter than this,
* so falling back to reading would not provide more data. If peek()
* returns zero bytes, this call will instead attempt to read(). This
* will require that the stream can be rewind()ed.
*
* If SkPngChunkReader is not NULL, take a ref and pass it to libpng if
* the image is a png.
*
* If the SkPngChunkReader is not NULL then:
* If the image is not a PNG, the SkPngChunkReader will be ignored.
* If the image is a PNG, the SkPngChunkReader will be reffed.
@ -252,18 +277,6 @@ public:
*/
Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
/**
* Some images may initially report that they have alpha due to the format
* of the encoded data, but then never use any colors which have alpha
* less than 100%. This function can be called *after* decoding to
* determine if such an image truly had alpha. Calling it before decoding
* is undefined.
* FIXME: see skbug.com/3582.
*/
bool reallyHasAlpha() const {
return this->onReallyHasAlpha();
}
/**
* The remaining functions revolve around decoding scanlines.
*/
@ -400,6 +413,8 @@ public:
/**
* An enum representing the order in which scanlines will be returned by
* the scanline decoder.
*
* This is undefined before startScanlineDecode() is called.
*/
SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); }
@ -415,9 +430,9 @@ public:
int nextScanline() const { return this->outputScanline(fCurrScanline); }
/**
* Returns the output y-coordinate of the row that corresponds to an input
* y-coordinate. The input y-coordinate represents where the scanline
* is located in the encoded data.
* Returns the output y-coordinate of the row that corresponds to an input
* y-coordinate. The input y-coordinate represents where the scanline
* is located in the encoded data.
*
* This will equal inputScanline, except in the case of strangely
* encoded image types (bottom-up bmps, interlaced gifs).
@ -459,8 +474,6 @@ protected:
return false;
}
virtual bool onReallyHasAlpha() const { return false; }
/**
* If the stream was previously read, attempt to rewind.
*
@ -529,14 +542,22 @@ protected:
virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; }
/**
* Update the next scanline. Used by interlaced png.
* Update the current scanline. Used by interlaced png.
*/
void updateNextScanline(int newY) { fCurrScanline = newY; }
void updateCurrScanline(int newY) { fCurrScanline = newY; }
const SkImageInfo& dstInfo() const { return fDstInfo; }
const SkCodec::Options& options() const { return fOptions; }
/**
* Returns the number of scanlines that have been decoded so far.
* This is unaffected by the SkScanlineOrder.
*
* Returns -1 if we have not started a scanline decode.
*/
int currScanline() const { return fCurrScanline; }
virtual int onOutputScanline(int inputScanline) const;
private:
@ -610,5 +631,6 @@ private:
virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; }
friend class SkSampledCodec;
friend class SkIcoCodec;
};
#endif // SkCodec_DEFINED

View File

@ -54,12 +54,24 @@ public:
*/
SkBitmap(const SkBitmap& src);
/**
* Copy the settings from the src into this bitmap. If the src has pixels
* allocated, ownership of the pixels will be taken.
*/
SkBitmap(SkBitmap&& src);
~SkBitmap();
/** Copies the src bitmap into this bitmap. Ownership of the src bitmap's pixels remains
with the src bitmap.
/** Copies the src bitmap into this bitmap. Ownership of the src
bitmap's pixels is shared with the src bitmap.
*/
SkBitmap& operator=(const SkBitmap& src);
/** Copies the src bitmap into this bitmap. Takes ownership of the src
bitmap's pixels.
*/
SkBitmap& operator=(SkBitmap&& src);
/** Swap the fields of the two bitmaps. This routine is guaranteed to never fail or throw.
*/
// This method is not exported to java.
@ -294,6 +306,14 @@ public:
return this->installPixels(info, pixels, rowBytes, NULL, NULL, NULL);
}
/**
* Call installPixels with no ReleaseProc specified. This means
* that the caller must ensure that the specified pixels and
* colortable are valid for the lifetime of the created bitmap
* (and its pixelRef).
*/
bool installPixels(const SkPixmap&);
/**
* Calls installPixels() with the value in the SkMask. The caller must
* ensure that the specified mask pixels are valid for the lifetime

View File

@ -37,6 +37,16 @@ class SkSurface;
class SkSurface_Base;
class SkTextBlob;
/*
* If you want the legacy cliptolayer flag (i.e. android), then you must have the new
* legacy saveflags.
*/
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
#ifndef SK_SUPPORT_LEGACY_SAVEFLAGS
#define SK_SUPPORT_LEGACY_SAVEFLAGS
#endif
#endif
/** \class SkCanvas
A Canvas encapsulates all of the state about drawing into a device (bitmap).
@ -53,6 +63,10 @@ class SkTextBlob;
etc.
*/
class SK_API SkCanvas : public SkRefCnt {
enum PrivateSaveLayerFlags {
kDontClipToLayer_PrivateSaveLayerFlag = 1 << 31,
};
public:
/**
* Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the
@ -281,6 +295,7 @@ public:
///////////////////////////////////////////////////////////////////////////
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
enum SaveFlags {
/** save the matrix state, restoring it on restore() */
// [deprecated] kMatrix_SaveFlag = 0x01,
@ -307,6 +322,7 @@ public:
#endif
kARGB_ClipLayer_SaveFlag = 0x1F
};
#endif
/** This call saves the current matrix, clip, and drawFilter, and pushes a
copy onto a private stack. Subsequent calls to translate, scale,
@ -336,6 +352,14 @@ public:
return this->saveLayer(&bounds, paint);
}
/**
* Temporary name.
* Will allow any requests for LCD text to be respected, so the caller must be careful to
* only draw on top of opaque sections of the layer to get good results.
*/
int saveLayerPreserveLCDTextRequests(const SkRect* bounds, const SkPaint* paint);
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
/** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead.
This behaves the same as saveLayer(const SkRect*, const SkPaint*),
@ -353,6 +377,7 @@ public:
*/
SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
#endif
/** This behaves the same as save(), but in addition it allocates an
offscreen bitmap. All drawing calls are directed there, and only when
@ -367,6 +392,7 @@ public:
*/
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha);
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
/** DEPRECATED - use saveLayerAlpha(const SkRect*, U8CPU) instead.
This behaves the same as saveLayerAlpha(const SkRect*, U8CPU),
@ -383,6 +409,43 @@ public:
*/
SK_ATTR_EXTERNALLY_DEPRECATED("SaveFlags use is deprecated")
int saveLayerAlpha(const SkRect* bounds, U8CPU alpha, SaveFlags flags);
#endif
enum {
kIsOpaque_SaveLayerFlag = 1 << 0,
kPreserveLCDText_SaveLayerFlag = 1 << 1,
#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG
kDontClipToLayer_Legacy_SaveLayerFlag = kDontClipToLayer_PrivateSaveLayerFlag,
#endif
};
typedef uint32_t SaveLayerFlags;
struct SaveLayerRec {
SaveLayerRec()
: fBounds(nullptr), fPaint(nullptr), fBackdrop(nullptr), fSaveLayerFlags(0)
{}
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, SaveLayerFlags saveLayerFlags = 0)
: fBounds(bounds)
, fPaint(paint)
, fBackdrop(nullptr)
, fSaveLayerFlags(saveLayerFlags)
{}
SaveLayerRec(const SkRect* bounds, const SkPaint* paint, const SkImageFilter* backdrop,
SaveLayerFlags saveLayerFlags)
: fBounds(bounds)
, fPaint(paint)
, fBackdrop(backdrop)
, fSaveLayerFlags(saveLayerFlags)
{}
const SkRect* fBounds; // optional
const SkPaint* fPaint; // optional
const SkImageFilter* fBackdrop; // optional
SaveLayerFlags fSaveLayerFlags;
};
int saveLayer(const SaveLayerRec&);
/** 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
@ -606,8 +669,8 @@ public:
* 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.
* dependent and one legal implementation is to do nothing. This method
* ignores the current 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
@ -617,7 +680,7 @@ public:
void discard() { this->onDiscard(); }
/**
* Fill the entire canvas' bitmap (restricted to the current clip) with the
* Fill the entire canvas (restricted to the current clip) with the
* specified paint.
* @param paint The paint used to fill the canvas
*/
@ -904,19 +967,6 @@ public:
void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst,
const SkPaint* paint = NULL);
/** Draw the specified bitmap, with its top/left corner at (x,y),
NOT transformed by the current matrix. Note: if the paint
contains a maskfilter that generates a mask which extends beyond the
bitmap's original width/height, then the bitmap will be drawn as if it
were in a Shader with CLAMP mode. Thus the color outside of the original
width/height will be the edge color replicated.
@param bitmap The bitmap to be drawn
@param left The position of the left side of the bitmap being drawn
@param top The position of the top side of the bitmap being drawn
@param paint The paint used to draw the bitmap, or NULL
*/
void drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint = NULL);
/** Draw the text, with origin at (x,y), using the specified paint.
The origin is interpreted based on the Align setting in the paint.
@param text The text to be drawn
@ -1223,14 +1273,15 @@ protected:
// Subclass save/restore notifiers.
// Overriders should call the corresponding INHERITED method up the inheritance chain.
// willSaveLayer()'s return value may suppress full layer allocation.
// getSaveLayerStrategy()'s return value may suppress full layer allocation.
enum SaveLayerStrategy {
kFullLayer_SaveLayerStrategy,
kNoLayer_SaveLayerStrategy
kNoLayer_SaveLayerStrategy,
};
virtual void willSave() {}
virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) {
// Overriders should call the corresponding INHERITED method up the inheritance chain.
virtual SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) {
return kFullLayer_SaveLayerStrategy;
}
virtual void willRestore() {}
@ -1285,7 +1336,6 @@ protected:
SrcRectConstraint);
virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*);
virtual void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*);
enum ClipEdgeStyle {
kHard_ClipEdgeStyle,
@ -1311,11 +1361,21 @@ protected:
// returns false if the entire rectangle is entirely clipped out
// If non-NULL, The imageFilter parameter will be used to expand the clip
// and offscreen bounds for any margin required by the filter DAG.
bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
SkIRect* intersection,
bool clipRectBounds(const SkRect* bounds, SaveLayerFlags, SkIRect* intersection,
const SkImageFilter* imageFilter = NULL);
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
// Needed by SkiaCanvasProxy in Android. Make sure that class is updated
// before removing this method.
static uint32_t SaveLayerFlagsToSaveFlags(SaveLayerFlags);
#endif
private:
static bool BoundsAffectsClip(SaveLayerFlags);
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
static uint32_t SaveFlagsToSaveLayerFlags(SaveFlags);
#endif
static SaveLayerFlags LegacySaveFlagsToSaveLayerFlags(uint32_t legacySaveFlags);
enum ShaderOverrideOpacity {
kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image)
kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque
@ -1375,6 +1435,7 @@ private:
friend class SkNoSaveLayerCanvas; // InitFlags
friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags)
friend class SkPictureRecord; // predrawNotify (why does it need it? <reed>)
friend class SkPicturePlayback; // SaveFlagsToSaveLayerFlags
enum InitFlags {
kDefault_InitFlags = 0,
@ -1406,7 +1467,7 @@ private:
const SkRect& dst, const SkPaint* paint,
SrcRectConstraint);
void internalDrawPaint(const SkPaint& paint);
void internalSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags, SaveLayerStrategy);
void internalSaveLayer(const SaveLayerRec&, SaveLayerStrategy);
void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice);
// shared by save() and saveLayer()
@ -1428,6 +1489,10 @@ private:
*/
bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const;
/**
* Returns true if the paint's imagefilter can be invoked directly, without needed a layer.
*/
bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
/* These maintain a cache of the clip bounds in local coordinates,
(converted to 2s-compliment if floats are slow).
@ -1505,49 +1570,7 @@ private:
};
#define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore)
/**
* If the caller wants read-only access to the pixels in a canvas, it can just
* call canvas->peekPixels(), since that is the fastest way to "peek" at the
* pixels on a raster-backed canvas.
*
* If the canvas has pixels, but they are not readily available to the CPU
* (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will
* succeed (though be slower, since it will return a copy of the pixels).
*
* SkAutoROCanvasPixels encapsulates these two techniques, trying first to call
* peekPixels() (for performance), but if that fails, calling readPixels() and
* storing the copy locally.
*
* The caller must respect the restrictions associated with peekPixels(), since
* that may have been called: The returned information is invalidated if...
* - any API is called on the canvas (or its parent surface if present)
* - the canvas goes out of scope
*/
class SkAutoROCanvasPixels : SkNoncopyable {
public:
SkAutoROCanvasPixels(SkCanvas* canvas);
// returns NULL on failure
const void* addr() const { return fAddr; }
// undefined if addr() == NULL
size_t rowBytes() const { return fRowBytes; }
// undefined if addr() == NULL
const SkImageInfo& info() const { return fInfo; }
// helper that, if returns true, installs the pixels into the bitmap. Note
// that the bitmap may reference the address returned by peekPixels(), so
// the caller must respect the restrictions associated with peekPixels().
bool asROBitmap(SkBitmap*) const;
private:
SkBitmap fBitmap; // used if peekPixels() fails
const void* fAddr; // NULL on failure
SkImageInfo fInfo;
size_t fRowBytes;
};
#ifdef SK_SUPPORT_LEGACY_SAVEFLAGS
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));
@ -1558,6 +1581,7 @@ static inline SkCanvas::SaveFlags& operator|=(SkCanvas::SaveFlags& lhs,
lhs = lhs | rhs;
return lhs;
}
#endif
class SkCanvasClipVisitor {
public:

View File

@ -106,13 +106,6 @@ public:
*/
static SkColorFilter* CreateModeFilter(SkColor c, SkXfermode::Mode mode);
/** Create a colorfilter that multiplies the RGB channels by one color, and
then adds a second color, pinning the result for each component to
[0..255]. The alpha components of the mul and add arguments
are ignored.
*/
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
/** Construct a colorfilter whose effect is to first apply the inner filter and then apply
* the outer filter to the result of the inner's.
* The reference counts for outer and inner are incremented.

View File

@ -333,16 +333,26 @@ protected:
const SkPaint*);
struct CreateInfo {
static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry);
static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry,
bool preserveLCDText);
// The constructor may change the pixel geometry based on other parameters.
CreateInfo(const SkImageInfo& info,
TileUsage tileUsage,
SkPixelGeometry geo,
bool forImageFilter = false)
SkPixelGeometry geo)
: fInfo(info)
, fTileUsage(tileUsage)
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo))
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, false))
, fForImageFilter(false) {}
CreateInfo(const SkImageInfo& info,
TileUsage tileUsage,
SkPixelGeometry geo,
bool preserveLCDText,
bool forImageFilter)
: fInfo(info)
, fTileUsage(tileUsage)
, fPixelGeometry(AdjustGeometry(info, tileUsage, geo, preserveLCDText))
, fForImageFilter(forImageFilter) {}
const SkImageInfo fInfo;
@ -374,9 +384,13 @@ private:
friend class SkDeviceFilteredPaint;
friend class SkImageFilter::DeviceProxy;
friend class SkNoPixelsBitmapDevice;
friend class SkSurface_Raster;
/**
* Calls through to drawSprite, processing imagefilter as needed.
*/
void drawBitmapAsSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&);
// used to change the backend's pixels (and possibly config/rowbytes)
// but cannot change the width/height, so there should be no change to
// any clip information.

View File

@ -16,6 +16,7 @@
#include "SkTime.h"
class SkCanvas;
class SkPixelSerializer;
class SkWStream;
/** SK_ScalarDefaultDPI is 72 DPI.
@ -57,6 +58,24 @@ public:
static SkDocument* CreatePDF(SkWStream*,
SkScalar dpi = SK_ScalarDefaultRasterDPI);
/**
* @param jpegEncoder For PDF documents, if a jpegEncoder is set,
* use it to encode SkImages and SkBitmaps as [JFIF]JPEGs.
* This feature is deprecated and is only supplied for
* backwards compatability.
*
* The prefered method to create PDFs with JPEG images is
* to use SkImage::NewFromEncoded() and not jpegEncoder.
* Chromium uses NewFromEncoded.
*
* If the encoder is unset, or if jpegEncoder->onEncode()
* returns NULL, fall back on encoding images losslessly
* with Deflate.
*/
static SkDocument* CreatePDF(SkWStream*,
SkScalar dpi,
SkPixelSerializer* jpegEncoder);
/**
* Create a PDF-backed document, writing the results into a file.
*/

View File

@ -16,6 +16,8 @@ class SkCanvas;
class SkPaint;
/**
* DEPRECATED - use SkPaintFilterCanvas instead.
*
* Right before something is being draw, filter() is called with the
* paint. The filter may modify the paint as it wishes, which will then be
* used for the actual drawing. Note: this modification only lasts for the

View File

@ -86,9 +86,9 @@ typedef int32_t SkFixed;
#if defined(SK_SUPPORT_LEGACY_DIVBITS_UB)
#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16)
#else
// TODO(reed): this clamp shouldn't be needed. Use SkToS32().
// The divide may exceed 32 bits. Clamp to a signed 32 bit result.
#define SkFixedDiv(numer, denom) \
SkTPin<int32_t>(((int64_t)numer << 16) / denom, SK_MinS32, SK_MaxS32)
SkToS32(SkTPin<int64_t>((SkLeftShift((int64_t)numer, 16) / denom), SK_MinS32, SK_MaxS32))
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////
@ -145,9 +145,9 @@ inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) {
typedef int64_t SkFixed3232; // 32.32
#define SkIntToFixed3232(x) ((SkFixed3232)(x) << 32)
#define SkIntToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 32))
#define SkFixed3232ToInt(x) ((int)((x) >> 32))
#define SkFixedToFixed3232(x) ((SkFixed3232)(x) << 16)
#define SkFixedToFixed3232(x) (SkLeftShift((SkFixed3232)(x), 16))
#define SkFixed3232ToFixed(x) ((SkFixed)((x) >> 16))
#define SkFloatToFixed3232(x) ((SkFixed3232)((x) * (65536.0f * 65536.0f)))

View File

@ -49,7 +49,7 @@ class SkPrivateEffectInitializer;
#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \
private: \
static SkFlattenable* CreateProc(SkReadBuffer&); \
friend class ::SkPrivateEffectInitializer; \
friend class SkFlattenable::PrivateInitializer; \
public: \
Factory getFactory() const override { return CreateProc; }
@ -108,6 +108,13 @@ public:
*/
virtual void flatten(SkWriteBuffer&) const {}
protected:
class PrivateInitializer {
public:
static void InitCore();
static void InitEffects();
};
private:
static void InitializeFlattenablesIfNeeded();

View File

@ -267,7 +267,7 @@ public:
* attempt to reuse existing encoded data (as returned by refEncoded).
*
* We defer to the SkPixelSerializer both for vetting existing encoded data
* (useEncodedData) and for encoding the image (encodePixels) when no such data is
* (useEncodedData) and for encoding the image (encode) when no such data is
* present or is rejected by the serializer.
*
* If not specified, we use a default serializer which 1) always accepts existing data
@ -324,28 +324,6 @@ public:
*/
bool isLazyGenerated() const;
/**
* Apply the specified filter to this image, and return the result as a new image.
*
* if forceResultToOriginalSize is true, then the resulting image will be the same size as the
* src, regardless of the normal output of the filter.
*
* If offset is non-null, it is set to the relative offset needed to draw the resulting image
* in the same logical place as the original.
*
* e.g.
* If the filter makes the result larger by a margin of 4 the output would be:
* result->width() == this->width + 8
* result->height() == this->height + 8
* offset.x() == -4
* offset.y() == -4
*
* If the filter fails to create a resulting image, null is returned, and the offset parameter
* (if specified) will be undefined.
*/
SkImage* applyFilter(SkImageFilter* filter, SkIPoint* offset,
bool forceResultToOriginalSize) const;
protected:
SkImage(int width, int height, uint32_t uniqueID);

View File

@ -16,8 +16,6 @@
#include "SkTRegistry.h"
#include "SkTypes.h"
//#define SK_LEGACY_PEEKER
class SkStream;
class SkStreamRewindable;
@ -129,18 +127,6 @@ public:
*/
bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; }
#ifdef SK_LEGACY_PEEKER
// Android subclasses SkImageDecoder::Peeker, which has been changed into SkPngChunkReader.
// Temporarily use this class until Android can be updated to directly inherit from
// SkPngChunkReader.
class Peeker : public SkPngChunkReader {
public:
bool readChunk(const char tag[], const void* data, size_t length) final {
return this->peek(tag, data, length);
}
virtual bool peek(const char tag[], const void* data, size_t length) = 0;
};
#endif
SkPngChunkReader* getPeeker() const { return fPeeker; }
SkPngChunkReader* setPeeker(SkPngChunkReader*);

View File

@ -12,6 +12,8 @@
#include "SkTRegistry.h"
class SkBitmap;
class SkPixelSerializer;
class SkPixmap;
class SkData;
class SkWStream;
@ -64,11 +66,17 @@ public:
Type, int quality);
static SkData* EncodeData(const SkBitmap&, Type, int quality);
static SkData* EncodeData(const SkPixmap&, Type, int quality);
static bool EncodeFile(const char file[], const SkBitmap&, Type,
int quality);
static bool EncodeStream(SkWStream*, const SkBitmap&, Type,
int quality);
/** Uses SkImageEncoder to serialize images that are not already
encoded as SkImageEncoder::kPNG_Type images. */
static SkPixelSerializer* CreatePixelSerializer();
protected:
/**
* Encode bitmap 'bm' in the desired format, writing results to

View File

@ -42,33 +42,25 @@ public:
virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0;
virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0;
virtual void purge() {}
};
enum SizeConstraint {
kExact_SizeConstraint,
kApprox_SizeConstraint,
virtual void purgeByImageFilterId(uint32_t) {}
};
class Context {
public:
Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache,
SizeConstraint constraint)
Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache)
: fCTM(ctm)
, fClipBounds(clipBounds)
, fCache(cache)
, fSizeConstraint(constraint)
{}
const SkMatrix& ctm() const { return fCTM; }
const SkIRect& clipBounds() const { return fClipBounds; }
Cache* cache() const { return fCache; }
SizeConstraint sizeConstraint() const { return fSizeConstraint; }
private:
SkMatrix fCTM;
SkIRect fClipBounds;
Cache* fCache;
SizeConstraint fSizeConstraint;
};
class CropRect {
@ -106,11 +98,17 @@ public:
uint32_t fFlags;
};
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled
kNever_TileUsage, //!< the created device will never be drawn tiled
};
class Proxy {
public:
virtual ~Proxy() {}
virtual SkBaseDevice* createDevice(int width, int height) = 0;
virtual SkBaseDevice* createDevice(int width, int height,
TileUsage usage = kNever_TileUsage) = 0;
// Returns true if the proxy handled the filter itself. If this returns
// false then the filter's code will be called.
@ -123,7 +121,8 @@ public:
public:
DeviceProxy(SkBaseDevice* device) : fDevice(device) {}
SkBaseDevice* createDevice(int width, int height) override;
SkBaseDevice* createDevice(int width, int height,
TileUsage usage = kNever_TileUsage) override;
// Returns true if the proxy handled the filter itself. If this returns
// false then the filter's code will be called.
@ -199,12 +198,7 @@ public:
* replaced by the returned colorfilter. i.e. the two effects will affect drawing in the
* same way.
*/
bool asAColorFilter(SkColorFilter** filterPtr) const {
return this->countInputs() > 0 &&
NULL == this->getInput(0) &&
!this->affectsTransparentBlack() &&
this->isColorFilterNode(filterPtr);
}
bool asAColorFilter(SkColorFilter** filterPtr) const;
/**
* Returns the number of inputs this filter will accept (some inputs can
@ -240,7 +234,7 @@ public:
virtual void computeFastBounds(const SkRect&, SkRect*) const;
// Can this filter DAG compute the resulting bounds of an object-space rectangle?
bool canComputeFastBounds() const;
virtual bool canComputeFastBounds() const;
/**
* If this filter can be represented by another filter + a localMatrix, return that filter,
@ -256,11 +250,6 @@ public:
SkImageFilter* input = NULL);
#if SK_SUPPORT_GPU
/**
* Wrap the given texture in a texture-backed SkBitmap.
*/
static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result);
// Helper function which invokes GPU filter processing on the
// input at the specified "index". If the input is null, it leaves
// "result" and "offset" untouched, and returns true. If the input
@ -268,7 +257,7 @@ public:
// Otherwise, the filter will be processed in software and
// uploaded to the GPU.
bool filterInputGPU(int index, SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* offset, bool relaxSizeConstraint = true) const;
SkBitmap* result, SkIPoint* offset) const;
#endif
SK_TO_STRING_PUREVIRT()
@ -351,6 +340,25 @@ protected:
// implementation recursively unions all input bounds, or returns false if
// no inputs.
virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const;
enum MapDirection {
kForward_MapDirection,
kReverse_MapDirection
};
/**
* Performs a forwards or reverse mapping of the given rect to accommodate
* this filter's margin requirements. kForward_MapDirection is used to
* determine the destination pixels which would be touched by filtering
* the given given source rect (e.g., given source bitmap bounds,
* determine the optimal bounds of the filtered offscreen bitmap).
* kReverse_MapDirection is used to determine which pixels of the
* input(s) would be required to fill the given destination rect
* (e.g., clip bounds). NOTE: these operations may not be the
* inverse of the other. For example, blurring expands the given rect
* in both forward and reverse directions. Unlike
* onFilterBounds(), this function is non-recursive.
*/
virtual void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const;
// Helper function which invokes filter processing on the input at the
// specified "index". If the input is null, it leaves "result" and
@ -358,7 +366,7 @@ protected:
// calls filterImage() on that input, and returns true on success.
// i.e., return !getInput(index) || getInput(index)->filterImage(...);
bool filterInput(int index, Proxy*, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* offset, bool relaxSizeConstraint = true) const;
SkBitmap* result, SkIPoint* offset) const;
/**
* Return true (and return a ref'd colorfilter) if this node in the DAG is just a
@ -411,12 +419,12 @@ protected:
const SkIRect& bounds) const;
/**
* Returns true if this filter can cause transparent black pixels to become
* visible (ie., alpha > 0). The default implementation returns false. This
* function is non-recursive, i.e., only queries this filter and not its
* inputs.
* Creates a modified Context for use when recursing up the image filter DAG.
* The clip bounds are adjusted to accommodate any margins that this
* filter requires by calling this node's
* onFilterNodeBounds(..., kReverse_MapDirection).
*/
virtual bool affectsTransparentBlack() const;
Context mapContext(const Context& ctx) const;
private:
friend class SkGraphics;

View File

@ -22,6 +22,12 @@ class SkMatrix;
class SkPaint;
class SkPicture;
#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX
#define SK_REFENCODEDDATA_CTXPARAM
#else
#define SK_REFENCODEDDATA_CTXPARAM GrContext* ctx
#endif
/**
* Takes ownership of SkImageGenerator. If this method fails for
* whatever reason, it will return false and immediatetely delete
@ -64,12 +70,20 @@ public:
/**
* Return a ref to the encoded (i.e. compressed) representation,
* of this data.
* of this data. If the GrContext is non-null, then the caller is only interested in
* gpu-specific formats, so the impl may return null even if they have encoded data,
* assuming they know it is not suitable for the gpu.
*
* If non-NULL is returned, the caller is responsible for calling
* unref() on the data when it is finished.
*/
SkData* refEncodedData() { return this->onRefEncodedData(); }
SkData* refEncodedData(GrContext* ctx = nullptr) {
#ifdef SK_SUPPORT_LEGACY_REFENCODEDDATA_NOCTX
return this->onRefEncodedData();
#else
return this->onRefEncodedData(ctx);
#endif
}
/**
* Return the ImageInfo associated with this generator.
@ -230,7 +244,7 @@ public:
protected:
SkImageGenerator(const SkImageInfo& info);
virtual SkData* onRefEncodedData();
virtual SkData* onRefEncodedData(SK_REFENCODEDDATA_CTXPARAM);
virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
SkPMColor ctable[], int* ctableCount);

View File

@ -17,6 +17,8 @@
the 3-channel 3D format. These are passed to SkMaskFilter objects.
*/
struct SkMask {
SkMask() : fImage(nullptr) {}
enum Format {
kBW_Format, //!< 1bit per pixel mask (e.g. monochrome)
kA8_Format, //!< 8bits per pixel mask (e.g. antialiasing)

View File

@ -184,9 +184,7 @@ protected:
class NinePatch : ::SkNoncopyable {
public:
NinePatch() : fCache(NULL) {
fMask.fImage = NULL;
}
NinePatch() : fCache(nullptr) { }
~NinePatch();
SkMask fMask; // fBounds must have [0,0] in its top-left

View File

@ -635,15 +635,17 @@ public:
/**
* 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.
* left 2x2. If the max scale factor cannot be computed (for example overflow or perspective)
* -1 is returned.
*
* @return minumum scale factor
* @return minimum scale factor
*/
SkScalar getMinScale() const;
/**
* 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.
* left 2x2. If the max scale factor cannot be computed (for example overflow or perspective)
* -1 is returned.
*
* @return maximum scale factor
*/
@ -651,10 +653,10 @@ public:
/**
* 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.
* is scaleFactors[1]. If the min/max scale factors cannot be computed false is returned and the
* values of scaleFactors[] are undefined.
*/
bool getMinMaxScales(SkScalar scaleFactors[2]) const;
bool SK_WARN_UNUSED_RESULT getMinMaxScales(SkScalar scaleFactors[2]) const;
/**
* Attempt to decompose this matrix into a scale-only component and whatever remains, where

View File

@ -41,6 +41,7 @@ size_t sk_fwrite(const void* buffer, size_t byteCount, FILE*);
char* sk_fgets(char* str, int size, FILE* f);
void sk_fflush(FILE*);
void sk_fsync(FILE*);
bool sk_fseek(FILE*, size_t);
bool sk_fmove(FILE*, long);

View File

@ -631,13 +631,6 @@ public:
SkAnnotation* getAnnotation() const { return fAnnotation; }
SkAnnotation* setAnnotation(SkAnnotation*);
/**
* Returns true if there is an annotation installed on this paint, and
* the annotation specifics no-drawing.
*/
SK_ATTR_DEPRECATED("use getAnnotation and check for non-null")
bool isNoDrawAnnotation() const { return this->getAnnotation() != NULL; }
/**
* Return the paint's SkDrawLooper (if any). Does not affect the looper's
* reference count.
@ -1089,12 +1082,11 @@ private:
friend class SkCanvas;
friend class SkDraw;
friend class SkPDFDevice;
friend class GrBitmapTextContext;
friend class GrAtlasTextBlob;
friend class GrAtlasTextContext;
friend class GrDistanceFieldTextContext;
friend class GrStencilAndCoverTextContext;
friend class GrPathRendering;
friend class GrTextContext;
friend class GrTextUtils;
friend class GrGLPathRendering;
friend class SkScalerContext;
friend class SkTextToPathIter;

View File

@ -956,6 +956,14 @@ public:
return (Verb) fRawIter.next(pts);
}
/** Return what the next verb will be, but do not visit the next segment.
@return The verb for the next segment
*/
Verb peek() const {
return (Verb) fRawIter.peek();
}
SkScalar conicWeight() const {
return fRawIter.conicWeight();
}

View File

@ -89,8 +89,12 @@ private:
struct Segment {
SkScalar fDistance; // total distance up to this point
unsigned fPtIndex : 15; // index into the fPts array
unsigned fPtIndex; // index into the fPts array
#ifdef SK_SUPPORT_LEGACY_PATH_MEASURE_TVALUE
unsigned fTValue : 15;
#else
unsigned fTValue : 30;
#endif
unsigned fType : 2;
SkScalar getScalarT() const;

View File

@ -124,6 +124,7 @@ public:
@return The verb for the current segment
*/
uint8_t next(SkPoint pts[4]);
uint8_t peek() const;
SkScalar conicWeight() const { return *fConicWeights; }

View File

@ -225,7 +225,8 @@ public:
return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace);
}
bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
/** Populates dst with the pixels of this pixelRef, converting them to colorType. */
bool readPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subset = NULL);
/**
* Makes a deep copy of this PixelRef, respecting the requested config.
@ -299,7 +300,7 @@ protected:
*
* The base class implementation returns false;
*/
virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
virtual bool onReadPixels(SkBitmap* dst, SkColorType colorType, const SkIRect* subsetOrNull);
// default impl returns NULL.
virtual SkData* onRefEncodedData();

View File

@ -9,9 +9,9 @@
#define SkPixelSerializer_DEFINED
#include "SkRefCnt.h"
#include "SkPixmap.h"
class SkData;
struct SkImageInfo;
/**
* Interface for serializing pixels, e.g. SkBitmaps in an SkPicture.
@ -32,14 +32,12 @@ public:
* Call to get the client's version of encoding these pixels. If it
* returns NULL, serialize the raw pixels.
*/
SkData* encodePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes) {
return this->onEncodePixels(info, pixels, rowBytes);
}
SkData* encode(const SkPixmap& pixmap) { return this->onEncode(pixmap); }
protected:
/**
* Return true if you want to serialize the encoded data, false if you want
* another version serialized (e.g. the result of encodePixels).
* another version serialized (e.g. the result of this->encode()).
*/
virtual bool onUseEncodedData(const void* data, size_t len) = 0;
@ -47,6 +45,6 @@ protected:
* If you want to encode these pixels, return the encoded data as an SkData
* Return null if you want to serialize the raw pixels.
*/
virtual SkData* onEncodePixels(const SkImageInfo&, const void* pixels, size_t rowBytes) = 0;
virtual SkData* onEncode(const SkPixmap&) = 0;
};
#endif // SkPixelSerializer_DEFINED

View File

@ -300,14 +300,6 @@
# endif
#endif
#if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
#define SK_VECTORCALL __vectorcall
#elif defined(SK_CPU_ARM32)
#define SK_VECTORCALL __attribute__((pcs("aapcs-vfp")))
#else
#define SK_VECTORCALL
#endif
//////////////////////////////////////////////////////////////////////
#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1

View File

@ -30,7 +30,8 @@
#define SK_BUILD_FOR_ANDROID
#elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || \
defined(__OpenBSD__) || defined(__sun) || defined(__NetBSD__) || \
defined(__DragonFly__) || defined(__GLIBC__) || defined(__GNU__)
defined(__DragonFly__) || defined(__GLIBC__) || defined(__GNU__) || \
defined(__unix__)
#define SK_BUILD_FOR_UNIX
#elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
#define SK_BUILD_FOR_IOS

View File

@ -153,6 +153,12 @@ public:
return rr;
}
static SkRRect MakeRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) {
SkRRect rr;
rr.setRectXY(rect, xRad, yRad);
return rr;
}
/**
* Set this RR to match the supplied oval. All x radii will equal half the
* width and all y radii will equal half the height.

View File

@ -824,24 +824,6 @@ public:
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.

View File

@ -216,7 +216,7 @@ public:
void unref() const {
if (1 == sk_atomic_fetch_add(&fRefCnt, -1, sk_memory_order_acq_rel)) {
SkDEBUGCODE(fRefCnt = 1;) // restore the 1 for our destructor's assert
delete (const Derived*)this;
delete (const Derived*)this;
}
}
void deref() const { this->unref(); }

View File

@ -15,6 +15,7 @@
#include "SkPaint.h"
#include "../gpu/GrColor.h"
class SkColorFilter;
class SkPath;
class SkPicture;
class SkXfermode;
@ -72,31 +73,14 @@ public:
enum Flags {
//!< set if all of the colors will be opaque
kOpaqueAlpha_Flag = 0x01,
//! set if this shader's shadeSpan16() method can be called
kHasSpan16_Flag = 0x02,
/** Set this bit if the shader's native data type is instrinsically 16
bit, meaning that calling the 32bit shadeSpan() entry point will
mean the the impl has to up-sample 16bit data into 32bit. Used as a
a means of clearing a dither request if the it will have no effect
*/
kIntrinsicly16_Flag = 0x04,
kOpaqueAlpha_Flag = 1 << 0,
/** 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().
*/
kConstInY32_Flag = 0x08,
/** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
which may not always be the case, since shadeSpan16 may be
predithered, which would mean it was not const in Y, even though
the 32bit shadeSpan() would be const.
*/
kConstInY16_Flag = 0x10
kConstInY32_Flag = 1 << 1,
};
/**
@ -136,12 +120,6 @@ public:
*/
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
@ -149,14 +127,12 @@ public:
*/
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
* The const void* ctx is only const because all the implementations are const.
* This can be changed to non-const if a new shade proc needs to change the ctx.
*/
virtual void shadeSpan16(int x, int y, uint16_t[], int count);
typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
virtual ShadeProc asAShadeProc(void** ctx);
/**
* Similar to shadeSpan, but only returns the alpha-channel for a span.
@ -165,14 +141,6 @@ public:
*/
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());
}
// Notification from blitter::blitMask in case we need to see the non-alpha channels
virtual void set3DMask(const SkMask*) {}
@ -215,13 +183,6 @@ public:
*/
virtual size_t contextSize() const;
/**
* Helper to check the flags to know if it is legal to call shadeSpan16()
*/
static bool CanCallShadeSpan16(uint32_t flags) {
return (flags & kHasSpan16_Flag) != 0;
}
/**
* Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
* localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
@ -342,8 +303,23 @@ public:
#endif
//////////////////////////////////////////////////////////////////////////
// Factory methods for stock shaders
// Methods to create combinations or variants of shaders
/**
* Return a shader that will apply the specified localMatrix to this shader.
* The specified matrix will be applied before any matrix associated with this shader.
*/
SkShader* newWithLocalMatrix(const SkMatrix&) const;
/**
* Create a new shader that produces the same colors as invoking this shader and then applying
* the colorfilter.
*/
SkShader* newWithColorFilter(SkColorFilter*) const;
//////////////////////////////////////////////////////////////////////////
// Factory methods for stock shaders
/**
* Call this to create a new "empty" shader, that will not draw anything.
*/
@ -394,14 +370,6 @@ public:
const SkMatrix* localMatrix,
const SkRect* tile);
/**
* 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.

View File

@ -65,17 +65,18 @@ public:
/**
* Attempt to peek at size bytes.
* If this stream supports peeking, and it can peek size bytes, copy size
* bytes into buffer, and return true.
* If the stream does not support peeking, or cannot peek size bytes,
* return false and leave buffer unchanged.
* If this stream supports peeking, copy min(size, peekable bytes) into
* buffer, and return the number of bytes copied.
* If the stream does not support peeking, or cannot peek any bytes,
* return 0 and leave buffer unchanged.
* The stream is guaranteed to be in the same visible state after this
* call, regardless of success or failure.
* @param buffer Must not be NULL. Destination to copy bytes.
* @param buffer Must not be NULL, and must be at least size bytes. Destination
* to copy bytes.
* @param size Number of bytes to copy.
* @return Whether the peek was performed.
* @return The number of bytes peeked/copied.
*/
virtual bool peek(void* /* buffer */, size_t /* size */) const { return false; }
virtual size_t peek(void* /*buffer*/, size_t /*size*/) const { return 0; }
/** Returns true when all the bytes in the stream have been read.
* This may return true early (when there are no more bytes to be read)
@ -325,7 +326,7 @@ public:
size_t read(void* buffer, size_t size) override;
bool isAtEnd() const override;
bool peek(void* buffer, size_t size) const override;
size_t peek(void* buffer, size_t size) const override;
bool rewind() override;
SkMemoryStream* duplicate() const override;
@ -359,6 +360,7 @@ public:
bool write(const void* buffer, size_t size) override;
void flush() override;
void fsync();
size_t bytesWritten() const override;
private:

View File

@ -267,7 +267,22 @@ template <> inline void SkTSwap(SkString& a, SkString& b) {
a.swap(b);
}
enum SkStrSplitMode {
// Strictly return all results. If the input is ",," and the separator is ',' this will return
// an array of three empty strings.
kStrict_SkStrSplitMode,
// Only nonempty results will be added to the results. Multiple separators will be
// coalesced. Separators at the beginning and end of the input will be ignored. If the input is
// ",," and the separator is ',', this will return an empty vector.
kCoalesce_SkStrSplitMode
};
// Split str on any characters in delimiters into out. (Think, strtok with a sane API.)
void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode,
SkTArray<SkString>* out);
inline void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out);
}
#endif

View File

@ -12,6 +12,7 @@
#include "SkTypes.h"
#include <new>
#include <utility>
template <typename T, bool MEM_COPY = false> class SkTArray;
@ -23,11 +24,11 @@ inline void copy(SkTArray<T, true>* self, int dst, int src) {
}
template<typename T>
inline void copy(SkTArray<T, true>* self, const T* array) {
memcpy(self->fMemArray, array, self->fCount * sizeof(T));
sk_careful_memcpy(self->fMemArray, array, self->fCount * sizeof(T));
}
template<typename T>
inline void copyAndDelete(SkTArray<T, true>* self, char* newMemArray) {
memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T));
sk_careful_memcpy(newMemArray, self->fMemArray, self->fCount * sizeof(T));
}
template<typename T>
@ -198,7 +199,7 @@ public:
*/
template<class... Args> T& emplace_back(Args&&... args) {
T* newT = reinterpret_cast<T*>(this->push_back_raw(1));
return *new (newT) T(skstd::forward<Args>(args)...);
return *new (newT) T(std::forward<Args>(args)...);
}
/**

View File

@ -45,7 +45,7 @@ public:
SkTDArray<T> tmp(src.fArray, src.fCount);
this->swap(tmp);
} else {
memcpy(fArray, src.fArray, sizeof(T) * src.fCount);
sk_careful_memcpy(fArray, src.fArray, sizeof(T) * src.fCount);
fCount = src.fCount;
}
}

View File

@ -11,6 +11,7 @@
#include "../private/SkTemplates.h"
#include "SkTypes.h"
#include <new>
#include <utility>
/**
* Efficient way to defer allocating/initializing a class until it is needed
@ -50,7 +51,7 @@ public:
if (this->isValid()) {
fPtr->~T();
}
fPtr = new (SkTCast<T*>(fStorage.get())) T(skstd::forward<Args>(args)...);
fPtr = new (SkTCast<T*>(fStorage.get())) T(std::forward<Args>(args)...);
return fPtr;
}
@ -130,6 +131,8 @@ class SkTCopyOnFirstWrite {
public:
SkTCopyOnFirstWrite(const T& initial) : fObj(&initial) {}
SkTCopyOnFirstWrite(const T* initial) : fObj(initial) {}
// Constructor for delayed initialization.
SkTCopyOnFirstWrite() : fObj(NULL) {}

View File

@ -38,10 +38,6 @@ public:
static double GetNSecs();
};
#if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32)
extern SkMSec gForceTickCount;
#endif
#define SK_TIME_FACTOR 1
///////////////////////////////////////////////////////////////////////////////

View File

@ -24,6 +24,28 @@
#include <string.h>
/**
* sk_careful_memcpy() is just like memcpy(), but guards against undefined behavior.
*
* It is undefined behavior to call memcpy() with null dst or src, even if len is 0.
* If an optimizer is "smart" enough, it can exploit this to do unexpected things.
* memcpy(dst, src, 0);
* if (src) {
* printf("%x\n", *src);
* }
* In this code the compiler can assume src is not null and omit the if (src) {...} check,
* unconditionally running the printf, crashing the program if src really is null.
* Of the compilers we pay attention to only GCC performs this optimization in practice.
*/
static inline void* sk_careful_memcpy(void* dst, const void* src, size_t len) {
// When we pass >0 len we had better already be passing valid pointers.
// So we just need to skip calling memcpy when len == 0.
if (len) {
memcpy(dst,src,len);
}
return dst;
}
/** \file SkTypes.h
*/
@ -78,7 +100,10 @@ SK_API extern void* sk_calloc_throw(size_t size);
// bzero is safer than memset, but we can't rely on it, so... sk_bzero()
static inline void sk_bzero(void* buffer, size_t size) {
memset(buffer, 0, size);
// Please c.f. sk_careful_memcpy. It's undefined behavior to call memset(null, 0, 0).
if (size) {
memset(buffer, 0, size);
}
}
///////////////////////////////////////////////////////////////////////////////
@ -222,12 +247,6 @@ typedef int S16CPU;
*/
typedef unsigned U16CPU;
/**
* Meant to be faster than bool (doesn't promise to be 0 or 1,
* just 0 or non-zero
*/
typedef int SkBool;
/**
* Meant to be a small version of bool, for storage purposes. Will be 0 or 1
*/
@ -257,7 +276,7 @@ typedef uint8_t SkBool8;
/** Returns 0 or 1 based on the condition
*/
#define SkToBool(cond) ((cond) != 0)
#define SkToBool(cond) (!!(cond))
#define SK_MaxS16 32767
#define SK_MinS16 -32767
@ -281,6 +300,14 @@ static inline bool SkIsU16(long x) {
return (uint16_t)x == x;
}
static inline int32_t SkLeftShift(int32_t value, int32_t shift) {
return (int32_t) ((uint32_t) value << shift);
}
static inline int64_t SkLeftShift(int64_t value, int32_t shift) {
return (int64_t) ((uint64_t) value << shift);
}
//////////////////////////////////////////////////////////////////////////////
/** Returns the number of entries in an array (not a pointer) */
@ -408,17 +435,6 @@ template <typename T> static inline const T& SkTPin(const T& value, const T& min
return SkTMax(SkTMin(value, max), min);
}
static inline uint32_t SkSetClearShift(uint32_t bits, bool cond,
unsigned shift) {
SkASSERT((int)cond == 0 || (int)cond == 1);
return (bits & ~(1 << shift)) | ((int)cond << shift);
}
static inline uint32_t SkSetClearMask(uint32_t bits, bool cond,
uint32_t mask) {
return cond ? bits | mask : bits & ~mask;
}
///////////////////////////////////////////////////////////////////////////////
/** Use to combine multiple bits in a bitmask in a type safe way.

View File

@ -165,7 +165,7 @@ public:
*/
void write(const void* values, size_t size) {
SkASSERT(SkAlign4(size) == size);
memcpy(this->reserve(size), values, size);
sk_careful_memcpy(this->reserve(size), values, size);
}
/**
@ -186,7 +186,7 @@ public:
* Write size bytes from src, and pad to 4 byte alignment with zeroes.
*/
void writePad(const void* src, size_t size) {
memcpy(this->reservePad(size), src, size);
sk_careful_memcpy(this->reservePad(size), src, size);
}
/**

View File

@ -56,8 +56,7 @@ public:
@param style how to transform path at each point (based on the current
position and tangent)
*/
static SkPath1DPathEffect* Create(const SkPath& path, SkScalar advance, SkScalar phase,
Style style) {
static SkPathEffect* Create(const SkPath& path, SkScalar advance, SkScalar phase, Style style) {
return new SkPath1DPathEffect(path, advance, phase, style);
}

View File

@ -55,7 +55,7 @@ private:
class SK_API SkLine2DPathEffect : public Sk2DPathEffect {
public:
static SkLine2DPathEffect* Create(SkScalar width, const SkMatrix& matrix) {
static SkPathEffect* Create(SkScalar width, const SkMatrix& matrix) {
return new SkLine2DPathEffect(width, matrix);
}
@ -84,7 +84,7 @@ public:
* Stamp the specified path to fill the shape, using the matrix to define
* the latice.
*/
static SkPath2DPathEffect* Create(const SkMatrix& matrix, const SkPath& path) {
static SkPathEffect* Create(const SkMatrix& matrix, const SkPath& path) {
return new SkPath2DPathEffect(matrix, path);
}

View File

@ -22,6 +22,7 @@ public:
*/
static SkImageFilter* Create(const SkRegion& region, SkScalar innerThreshold,
SkScalar outerThreshold, SkImageFilter* input = NULL);
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP();
};
#endif

View File

@ -35,8 +35,8 @@ public:
kAll_BlurFlag = 0x07
};
static SkBlurDrawLooper* Create(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
uint32_t flags = kNone_BlurFlag) {
static SkDrawLooper* Create(SkColor color, SkScalar sigma, SkScalar dx, SkScalar dy,
uint32_t flags = kNone_BlurFlag) {
return new SkBlurDrawLooper(color, sigma, dx, dy, flags);
}

View File

@ -15,6 +15,9 @@ class SK_API SkBlurImageFilter : public SkImageFilter {
public:
static SkImageFilter* Create(SkScalar sigmaX, SkScalar sigmaY, SkImageFilter* input = NULL,
const CropRect* cropRect = NULL) {
if (0 == sigmaX && 0 == sigmaY && nullptr == cropRect) {
return SkSafeRef(input);
}
return new SkBlurImageFilter(sigmaX, sigmaY, input, cropRect);
}
@ -27,7 +30,8 @@ protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* offset) const override;
bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const override;
void onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
SkIRect* dst, MapDirection) const override;
bool canFilterImageGPU() const override { return true; }
bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result,
SkIPoint* offset) const override;

View File

@ -11,6 +11,7 @@
#include "SkColorFilter.h"
#include "SkData.h"
#include "../private/SkMutex.h"
#include "../private/SkTemplates.h"
class SK_API SkColorCubeFilter : public SkColorFilter {
public:
@ -55,7 +56,7 @@ private:
SkScalar* fColorToFactors[2];
SkScalar* fColorToScalar;
SkAutoMalloc fLutStorage;
SkAutoTMalloc<uint8_t> fLutStorage;
const int fCubeDimension;

View File

@ -25,7 +25,7 @@ protected:
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* loc) const override;
bool onIsColorFilterNode(SkColorFilter**) const override;
bool affectsTransparentBlack() const override;
bool canComputeFastBounds() const override;
private:
SkColorFilterImageFilter(SkColorFilter* cf,

View File

@ -13,13 +13,21 @@
class SK_API SkColorMatrixFilter : public SkColorFilter {
public:
static SkColorMatrixFilter* Create(const SkColorMatrix& cm) {
static SkColorFilter* Create(const SkColorMatrix& cm) {
return new SkColorMatrixFilter(cm);
}
static SkColorMatrixFilter* Create(const SkScalar array[20]) {
static SkColorFilter* Create(const SkScalar array[20]) {
return new SkColorMatrixFilter(array);
}
/**
* Create a colorfilter that multiplies the RGB channels by one color, and
* then adds a second color, pinning the result for each component to
* [0..255]. The alpha components of the mul and add arguments
* are ignored.
*/
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
uint32_t getFlags() const override;
bool asColorMatrix(SkScalar matrix[20]) const override;
@ -29,11 +37,6 @@ public:
const GrFragmentProcessor* asFragmentProcessor(GrContext*) const override;
#endif
struct State {
int32_t fArray[20];
int fShift;
};
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorMatrixFilter)
@ -46,13 +49,7 @@ protected:
private:
SkColorMatrix fMatrix;
float fTranspose[SkColorMatrix::kCount]; // for Sk4s
typedef void (*Proc)(const State&, unsigned r, unsigned g, unsigned b,
unsigned a, int32_t result[4]);
Proc fProc;
State fState;
uint32_t fFlags;
uint32_t fFlags;
void initState(const SkScalar array[20]);

View File

@ -20,8 +20,7 @@ public:
/** radius must be > 0 to have an effect. It specifies the distance from each corner
that should be "rounded".
*/
static SkCornerPathEffect* Create(SkScalar radius) { return new SkCornerPathEffect(radius); }
virtual ~SkCornerPathEffect();
static SkPathEffect* Create(SkScalar radius) { return new SkCornerPathEffect(radius); }
virtual bool filterPath(SkPath* dst, const SkPath& src,
SkStrokeRec*, const SkRect*) const override;
@ -34,6 +33,8 @@ public:
#endif
protected:
virtual ~SkCornerPathEffect();
explicit SkCornerPathEffect(SkScalar radius);
void flatten(SkWriteBuffer&) const override;

View File

@ -36,8 +36,7 @@ public:
Note: only affects stroked paths.
*/
static SkDashPathEffect* Create(const SkScalar intervals[], int count,
SkScalar phase) {
static SkPathEffect* Create(const SkScalar intervals[], int count, SkScalar phase) {
return new SkDashPathEffect(intervals, count, phase);
}
virtual ~SkDashPathEffect();

View File

@ -29,9 +29,7 @@ public:
they can pass in a different seedAssist to get a
different set of path segments.
*/
static SkDiscretePathEffect* Create(SkScalar segLength,
SkScalar deviation,
uint32_t seedAssist=0) {
static SkPathEffect* Create(SkScalar segLength, SkScalar deviation, uint32_t seedAssist = 0) {
return new SkDiscretePathEffect(segLength, deviation, seedAssist);
}

View File

@ -23,11 +23,11 @@ public:
~SkDisplacementMapEffect();
static SkDisplacementMapEffect* Create(ChannelSelectorType xChannelSelector,
ChannelSelectorType yChannelSelector,
SkScalar scale, SkImageFilter* displacement,
SkImageFilter* color = NULL,
const CropRect* cropRect = NULL);
static SkImageFilter* Create(ChannelSelectorType xChannelSelector,
ChannelSelectorType yChannelSelector,
SkScalar scale, SkImageFilter* displacement,
SkImageFilter* color = NULL,
const CropRect* cropRect = NULL);
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect)
@ -40,6 +40,7 @@ public:
virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&,
SkIRect* dst) const override;
void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
#if SK_SUPPORT_GPU
bool canFilterImageGPU() const override { return true; }

View File

@ -35,7 +35,8 @@ protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result,
SkIPoint* loc) const override;
bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const override;
void onFilterNodeBounds(const SkIRect& src, const SkMatrix&,
SkIRect* dst, MapDirection) const override;
private:
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor,

View File

@ -23,14 +23,14 @@ public:
uint8_t fSpecular; // exponent, 4.4 right now
};
static SkEmbossMaskFilter* Create(SkScalar blurSigma, const Light& light);
static SkMaskFilter* Create(SkScalar blurSigma, const Light& light);
// overrides from SkMaskFilter
// This method is not exported to java.
SkMask::Format getFormat() const override;
// This method is not exported to java.
virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
SkIPoint* margin) const override;
bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&,
SkIPoint* margin) const override;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmbossMaskFilter)

View File

@ -49,7 +49,7 @@ protected:
void flatten(SkWriteBuffer&) const override;
const SkImageFilterLight* light() const { return fLight.get(); }
SkScalar surfaceScale() const { return fSurfaceScale; }
bool affectsTransparentBlack() const override { return true; }
bool canComputeFastBounds() const override { return false; }
private:
typedef SkImageFilter INHERITED;

View File

@ -52,15 +52,15 @@ public:
passed to filterImage() is used instead.
@param cropRect The rectangle to which the output processing will be limited.
*/
static SkMatrixConvolutionImageFilter* Create(const SkISize& kernelSize,
const SkScalar* kernel,
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
TileMode tileMode,
bool convolveAlpha,
SkImageFilter* input = NULL,
const CropRect* cropRect = NULL);
static SkImageFilter* Create(const SkISize& kernelSize,
const SkScalar* kernel,
SkScalar gain,
SkScalar bias,
const SkIPoint& kernelOffset,
TileMode tileMode,
bool convolveAlpha,
SkImageFilter* input = NULL,
const CropRect* cropRect = NULL);
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter)
@ -79,8 +79,8 @@ protected:
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&,
SkBitmap* result, SkIPoint* loc) const override;
bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const override;
void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
bool canComputeFastBounds() const override;
#if SK_SUPPORT_GPU
bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&,

View File

@ -16,7 +16,8 @@
class SK_API SkMorphologyImageFilter : public SkImageFilter {
public:
void computeFastBounds(const SkRect& src, SkRect* dst) const override;
bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const override;
void onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst, MapDirection) const override;
/**
* All morphology procs have the same signature: src is the source buffer, dst the

View File

@ -30,7 +30,7 @@ protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* loc) const override;
bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const override;
void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
private:
SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input, const CropRect*);

View File

@ -0,0 +1,45 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPaintImageFilter_DEFINED
#define SkPaintImageFilter_DEFINED
#include "SkImageFilter.h"
#include "SkPaint.h"
class SK_API SkPaintImageFilter : public SkImageFilter {
public:
/** Create a new image filter which fills the given rectangle using the
* given paint. If no rectangle is specified, an output is produced with
* the same bounds as the input primitive (even though the input
* primitive's pixels are not used for processing).
* @param paint Paint to use when filling the rect.
* @param rect Rectangle of output pixels. If NULL or a given crop edge is
* not specified, the source primitive's bounds are used
* instead.
*/
static SkImageFilter* Create(const SkPaint& paint, const CropRect* rect = NULL);
bool canComputeFastBounds() const override;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPaintImageFilter)
protected:
void flatten(SkWriteBuffer&) const override;
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* loc) const override;
private:
SkPaintImageFilter(const SkPaint& paint, const CropRect* rect);
SkPaint fPaint;
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -80,7 +80,6 @@ public:
virtual ~PerlinNoiseShaderContext();
void shadeSpan(int x, int y, SkPMColor[], int count) override;
void shadeSpan16(int x, int y, uint16_t[], int count) override;
private:
SkPMColor shade(const SkPoint& point, StitchData& stitchData) const;

View File

@ -1,52 +0,0 @@
/*
* Copyright 2013 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkRectShaderImageFilter_DEFINED
#define SkRectShaderImageFilter_DEFINED
#include "SkImageFilter.h"
#include "SkRect.h"
class SkShader;
class SK_API SkRectShaderImageFilter : public SkImageFilter {
public:
/** Create a new image filter which fills the given rectangle with pixels
* produced by the given SkShader. If no rectangle is specified, an output
* is produced with the same bounds as the input primitive (even though
* the input primitive's pixels are not used for processing).
* @param s Shader to call for processing. Cannot be NULL. Will be
* ref'ed by the new image filter.
* @param rect Rectangle of output pixels in which to apply the shader.
* If NULL or a given crop edge is not specified, the source
* primitive's bounds are used instead.
*/
SK_ATTR_DEPRECATED("use Create(SkShader*, const CropRect*)")
static SkImageFilter* Create(SkShader* s, const SkRect& rect);
static SkImageFilter* Create(SkShader* s, const CropRect* rect = NULL);
bool affectsTransparentBlack() const override;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRectShaderImageFilter)
protected:
virtual ~SkRectShaderImageFilter();
void flatten(SkWriteBuffer&) const override;
bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result,
SkIPoint* loc) const override;
private:
SkRectShaderImageFilter(SkShader* s, const CropRect* rect);
SkShader* fShader;
typedef SkImageFilter INHERITED;
};
#endif

View File

@ -25,6 +25,7 @@ public:
SkBitmap* dst, SkIPoint* offset) const override;
bool onFilterBounds(const SkIRect& src, const SkMatrix&,
SkIRect* dst) const override;
void onFilterNodeBounds(const SkIRect&, const SkMatrix&, SkIRect*, MapDirection) const override;
void computeFastBounds(const SkRect& src, SkRect* dst) const override;
SK_TO_STRING_OVERRIDE()

View File

@ -23,9 +23,9 @@ class SK_API SkXfermodeImageFilter : public SkImageFilter {
public:
virtual ~SkXfermodeImageFilter();
static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
SkImageFilter* foreground = NULL,
const CropRect* cropRect = NULL) {
static SkImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
SkImageFilter* foreground = NULL,
const CropRect* cropRect = NULL) {
SkImageFilter* inputs[2] = { background, foreground };
return new SkXfermodeImageFilter(mode, inputs, cropRect);
}

View File

@ -70,7 +70,7 @@ public:
* called.
*/
const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
GrSLPrecision precision) const {
GrSLPrecision precision) const {
return fFloatPrecisions[shaderType][precision];
};
@ -118,11 +118,7 @@ public:
bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
bool stencilWrapOpsSupport() const { return fStencilWrapOpsSupport; }
bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
#if GR_FORCE_GPU_TRACE_DEBUGGING
bool gpuTracingSupport() const { return true; }
#else
bool gpuTracingSupport() const { return fGpuTracingSupport; }
#endif
bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
bool textureBarrierSupport() const { return fTextureBarrierSupport; }
@ -194,15 +190,8 @@ public:
// Will be 0 if MSAA is not supported
int maxSampleCount() const { return fMaxSampleCount; }
bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
SkASSERT(kGrPixelConfigCnt > config);
return fConfigRenderSupport[config][withMSAA];
}
bool isConfigTexturable(GrPixelConfig config) const {
SkASSERT(kGrPixelConfigCnt > config);
return fConfigTextureSupport[config];
}
virtual bool isConfigTexturable(GrPixelConfig config) const = 0;
virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0;
bool suppressPrints() const { return fSuppressPrints; }
@ -270,10 +259,6 @@ protected:
int fMaxTileSize;
int fMaxSampleCount;
// The first entry for each config is without msaa and the second is with.
bool fConfigRenderSupport[kGrPixelConfigCnt][2];
bool fConfigTextureSupport[kGrPixelConfigCnt];
private:
virtual void onApplyOptionsOverrides(const GrContextOptions&) {};

View File

@ -85,7 +85,7 @@ public:
return this->irect() == other.irect();
break;
}
SkFAIL("This should not occur\n");
return false;
}

View File

@ -186,11 +186,11 @@ typedef unsigned __int64 uint64_t;
#endif
/**
* GR_FORCE_GPU_TRACE_DEBUGGING will force gpu tracing/debug markers to be turned on. The trace
* markers will be printed out instead of making the backend calls to push and pop them.
* Enable batch debugging output as json. The enabler of this flag is responsible for making sure
* GrAuditTrail is reset occasionally.
* TODO make this runtime configurable
*/
#if !defined(GR_FORCE_GPU_TRACE_DEBUGGING)
#define GR_FORCE_GPU_TRACE_DEBUGGING 0
#if !defined(GR_BATCH_DEBUGGING_OUTPUT)
#define GR_BATCH_DEBUGGING_OUTPUT 0
#endif
#endif

View File

@ -15,9 +15,11 @@
#include "GrRenderTarget.h"
#include "GrTextureProvider.h"
#include "SkMatrix.h"
#include "../private/SkMutex.h"
#include "SkPathEffect.h"
#include "SkTypes.h"
#include "../private/GrAuditTrail.h"
#include "../private/GrSingleOwner.h"
#include "../private/SkMutex.h"
struct GrBatchAtlasConfig;
class GrBatchFontCache;
@ -354,9 +356,13 @@ public:
/** Enumerates all cached GPU resources and dumps their memory to traceMemoryDump. */
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
/** Draw font cache texture to render target */
void drawFontCache(const SkRect& rect, GrMaskFormat format, const SkPaint& paint,
GrRenderTarget* target);
/** Get pointer to atlas texture for given mask format */
GrTexture* getFontAtlasTexture(GrMaskFormat format);
GrAuditTrail* getAuditTrail() { return &fAuditTrail; }
/** This is only useful for debug purposes */
SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fSingleOwner; } )
private:
GrGpu* fGpu;
@ -391,6 +397,11 @@ private:
SkMutex fReadPixelsMutex;
SkMutex fTestPMConversionsMutex;
// In debug builds we guard against improper thread handling
// This guard is passed to the GrDrawingManager and, from there to all the
// GrDrawContexts. It is also passed to the GrTextureProvider and SkGpuDevice.
mutable GrSingleOwner fSingleOwner;
struct CleanUpData {
PFCleanUpFunc fFunc;
void* fInfo;
@ -402,6 +413,8 @@ private:
SkAutoTDelete<GrDrawingManager> fDrawingManager;
GrAuditTrail fAuditTrail;
// TODO: have the CMM use drawContexts and rm this friending
friend class GrClipMaskManager; // the CMM is friended just so it can call 'drawingManager'
friend class GrDrawingManager; // for access to drawingManager for ProgramUnitTest

View File

@ -21,6 +21,8 @@ struct GrContextOptions {
, fUseDrawInsteadOfPartialRenderTargetWrite(false)
, fImmediateMode(false)
, fClipBatchToBounds(false)
, fDrawBatchBounds(false)
, fMaxBatchLookback(-1)
, fUseShaderSwizzling(false) {}
// EXPERIMENTAL
@ -57,6 +59,14 @@ struct GrContextOptions {
verify that the clip bounds are conservative. */
bool fClipBatchToBounds;
/** For debugging purposes draw a wireframe device bounds rect for each GrBatch. The wire
frame rect is draw before the GrBatch in order to visualize batches that draw outside
of their dev bounds. */
bool fDrawBatchBounds;
/** For debugging, override the default maximum look-back window for GrBatch combining. */
int fMaxBatchLookback;
/** Force us to do all swizzling manually in the shader and don't rely on extensions to do
swizzling. */
bool fUseShaderSwizzling;

View File

@ -12,16 +12,17 @@
#include "GrRenderTarget.h"
#include "SkRefCnt.h"
#include "SkSurfaceProps.h"
#include "../private/GrSingleOwner.h"
class GrAuditTrail;
class GrClip;
class GrContext;
class GrDrawBatch;
class GrDrawPathBatchBase;
class GrDrawingManager;
class GrDrawTarget;
class GrPaint;
class GrPathProcessor;
class GrPathRange;
class GrPathRangeDraw;
class GrPipelineBuilder;
class GrRenderTarget;
class GrStrokeInfo;
@ -63,17 +64,6 @@ public:
SkScalar x, SkScalar y,
SkDrawFilter*, const SkIRect& clipBounds);
// drawPathsFromRange is thanks to GrStencilAndCoverTextContext
// TODO: remove once path batches can be created external to GrDrawTarget.
void drawPathsFromRange(const GrPipelineBuilder*,
const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
GrColor color,
GrPathRange* range,
GrPathRangeDraw* draw,
int /*GrPathRendering::FillType*/ fill,
const SkRect& bounds);
/**
* Provides a perfomance hint that the render target's contents are allowed
* to become undefined.
@ -274,17 +264,32 @@ public:
*/
void drawBatch(const GrClip&, const GrPaint&, GrDrawBatch*);
/**
* Draws a path batch. This needs to be separate from drawBatch because we install path stencil
* settings late.
*
* TODO: Figure out a better model that allows us to roll this method into drawBatch.
*/
void drawPathBatch(const GrPipelineBuilder&, GrDrawPathBatchBase*);
int width() const { return fRenderTarget->width(); }
int height() const { return fRenderTarget->height(); }
int numColorSamples() const { return fRenderTarget->numColorSamples(); }
GrRenderTarget* accessRenderTarget() { return fRenderTarget; }
///////////////////////////////////////////////////////////////////////////////////////////////
// Functions intended for internal use only.
void internal_drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch);
private:
friend class GrAtlasTextContext; // for access to drawBatch
friend class GrAtlasTextBlob; // for access to drawBatch
friend class GrDrawingManager; // for ctor
SkDEBUGCODE(void validate() const;)
GrDrawContext(GrDrawingManager*, GrRenderTarget*, const SkSurfaceProps* surfaceProps);
GrDrawContext(GrDrawingManager*, GrRenderTarget*, const SkSurfaceProps* surfaceProps,
GrAuditTrail*, GrSingleOwner*);
void internalDrawPath(GrPipelineBuilder*,
const SkMatrix& viewMatrix,
@ -308,6 +313,10 @@ private:
GrTextContext* fTextContext; // lazily gotten from GrContext::DrawingManager
SkSurfaceProps fSurfaceProps;
GrAuditTrail* fAuditTrail;
// In debug builds we guard against improper thread handling
SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
};
#endif

View File

@ -293,11 +293,13 @@ private:
#define GR_DECLARE_STATIC_UNIQUE_KEY(name) SK_DECLARE_STATIC_ONCE(name##_once)
/** Place inside function where the key is used. */
#define GR_DEFINE_STATIC_UNIQUE_KEY(name) \
static GrUniqueKey name; \
SkOnce(&name##_once, gr_init_static_unique_key_once, &name)
#define GR_DEFINE_STATIC_UNIQUE_KEY(name) \
static SkAlignedSTStorage<1, GrUniqueKey> name##_storage; \
SkOnce(&name##_once, gr_init_static_unique_key_once, &name##_storage); \
static const GrUniqueKey& name = *reinterpret_cast<GrUniqueKey*>(name##_storage.get());
static inline void gr_init_static_unique_key_once(GrUniqueKey* key) {
static inline void gr_init_static_unique_key_once(SkAlignedSTStorage<1,GrUniqueKey>* keyStorage) {
GrUniqueKey* key = new (keyStorage->get()) GrUniqueKey;
GrUniqueKey::Builder builder(key, GrUniqueKey::GenerateDomain(), 0);
}

View File

@ -91,6 +91,7 @@ static inline uint8_t GrRandomCoverage(SkRandom* random) {
switch (colorMode) {
case kZero_CoverageMode:
coverage = 0;
break;
case kAllOnes_CoverageMode:
coverage = 0xff;
break;

View File

@ -14,60 +14,33 @@
#include "SkRefCnt.h"
#include "SkShader.h"
/** A class representing the swizzle access pattern for a texture. Note that if the texture is
* an alpha-only texture then the alpha channel is substituted for other components. Any mangling
* to handle the r,g,b->a conversions for alpha textures is automatically included in the stage
* key. However, if a GrProcessor uses different swizzles based on its input then it must
* consider that variation in its key-generation.
/**
* Used to represent a texture that is required by a GrProcessor. It holds a GrTexture along with
* an associated GrTextureParams
*/
class GrTextureAccess : public SkNoncopyable {
public:
/**
* A default GrTextureAccess must have reset() called on it in a GrProcessor subclass's
* constructor if it will be accessible via GrProcessor::textureAccess().
* Must be initialized before adding to a GrProcessor's texture access list.
*/
GrTextureAccess();
/**
* Uses the default swizzle, "rgba".
*/
GrTextureAccess(GrTexture*, const GrTextureParams&);
explicit GrTextureAccess(GrTexture*,
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
/**
* swizzle must be a string between one and four (inclusive) characters containing only 'r',
* 'g', 'b', and/or 'a'.
*/
GrTextureAccess(GrTexture*, const char* swizzle, const GrTextureParams&);
GrTextureAccess(GrTexture*,
const char* swizzle,
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
void reset(GrTexture*, const GrTextureParams&);
void reset(GrTexture*,
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
void reset(GrTexture*, const char* swizzle, const GrTextureParams&);
void reset(GrTexture*,
const char* swizzle,
GrTextureParams::FilterMode = GrTextureParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode);
bool operator== (const GrTextureAccess& other) const {
#ifdef SK_DEBUG
// below assumes all chars in fSwizzle are initialized even if string is < 4 chars long.
SkASSERT(memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1) ==
strcmp(fSwizzle, other.fSwizzle));
#endif
return fParams == other.fParams &&
(this->getTexture() == other.getTexture()) &&
(0 == memcmp(fSwizzle, other.fSwizzle, sizeof(fSwizzle)-1));
bool operator==(const GrTextureAccess& that) const {
return this->getTexture() == that.getTexture() && fParams == that.fParams;
}
bool operator!= (const GrTextureAccess& other) const { return !(*this == other); }
bool operator!=(const GrTextureAccess& other) const { return !(*this == other); }
GrTexture* getTexture() const { return fTexture.get(); }
@ -76,26 +49,14 @@ public:
*/
const GrGpuResourceRef* getProgramTexture() const { return &fTexture; }
/**
* Returns a string representing the swizzle. The string is is null-terminated.
*/
const char* getSwizzle() const { return fSwizzle; }
/** Returns a mask indicating which components are referenced in the swizzle. The return
is a bitfield of GrColorComponentFlags. */
uint32_t swizzleMask() const { return fSwizzleMask; }
const GrTextureParams& getParams() const { return fParams; }
private:
void setSwizzle(const char*);
typedef GrTGpuResourceRef<GrTexture> ProgramTexture;
ProgramTexture fTexture;
GrTextureParams fParams;
uint32_t fSwizzleMask;
char fSwizzle[5];
typedef SkNoncopyable INHERITED;
};

View File

@ -11,6 +11,8 @@
#include "GrTexture.h"
#include "SkImageFilter.h"
class GrSingleOwner;
class SK_API GrTextureProvider {
public:
///////////////////////////////////////////////////////////////////////////
@ -42,15 +44,7 @@ public:
}
/** Finds a texture by unique key. If the texture is found it is ref'ed and returned. */
GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key) {
GrGpuResource* resource = this->findAndRefResourceByUniqueKey(key);
if (resource) {
GrTexture* texture = static_cast<GrSurface*>(resource)->asTexture();
SkASSERT(texture);
return texture;
}
return NULL;
}
GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key);
/**
* Determines whether a texture is associated with the unique key. If the texture is found it
@ -70,31 +64,6 @@ public:
*/
GrTexture* createApproxTexture(const GrSurfaceDesc&);
enum SizeConstraint {
kExact_SizeConstraint,
kApprox_SizeConstraint,
};
GrTexture* createTexture(const GrSurfaceDesc& desc, SizeConstraint constraint) {
switch (constraint) {
case kExact_SizeConstraint:
return this->createTexture(desc, true);
case kApprox_SizeConstraint:
return this->createApproxTexture(desc);
}
sk_throw();
return nullptr;
}
static SizeConstraint FromImageFilter(SkImageFilter::SizeConstraint constraint) {
if (SkImageFilter::kExact_SizeConstraint == constraint) {
return kExact_SizeConstraint;
} else {
SkASSERT(SkImageFilter::kApprox_SizeConstraint == constraint);
return kApprox_SizeConstraint;
}
}
/** Legacy function that no longer should be used. */
enum ScratchTexMatch {
kExact_ScratchTexMatch,
@ -134,7 +103,7 @@ public:
GrRenderTarget* wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
protected:
GrTextureProvider(GrGpu* gpu, GrResourceCache* cache) : fCache(cache), fGpu(gpu) {}
GrTextureProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* singleOwner);
/**
* Assigns a unique key to a resource. If the key is associated with another resource that
@ -186,6 +155,9 @@ protected:
private:
GrResourceCache* fCache;
GrGpu* fGpu;
// In debug builds we guard against improper thread handling
SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
};
#endif

View File

@ -363,26 +363,6 @@ static inline size_t GrBytesPerPixel(GrPixelConfig config) {
}
}
static inline size_t GrUnpackAlignment(GrPixelConfig config) {
SkASSERT(!GrPixelConfigIsCompressed(config));
switch (config) {
case kAlpha_8_GrPixelConfig:
return 1;
case kRGB_565_GrPixelConfig:
case kRGBA_4444_GrPixelConfig:
case kAlpha_half_GrPixelConfig:
case kRGBA_half_GrPixelConfig:
return 2;
case kRGBA_8888_GrPixelConfig:
case kBGRA_8888_GrPixelConfig:
case kSRGBA_8888_GrPixelConfig:
case kRGBA_float_GrPixelConfig:
return 4;
default:
return 0;
}
}
static inline bool GrPixelConfigIsOpaque(GrPixelConfig config) {
switch (config) {
case kETC1_GrPixelConfig:

View File

@ -12,10 +12,10 @@
#include "SkTArray.h"
#include "SkRect.h"
/**
* Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
* but should be applicable to other shader languages.)
*/
/**
* Types of shader-language-specific boxed variables we can create. (Currently only GrGLShaderVars,
* but should be applicable to other shader languages.)
*/
enum GrSLType {
kVoid_GrSLType,
kFloat_GrSLType,
@ -26,8 +26,9 @@ enum GrSLType {
kMat44f_GrSLType,
kSampler2D_GrSLType,
kSamplerExternal_GrSLType,
kSampler2DRect_GrSLType,
kLast_GrSLType = kSamplerExternal_GrSLType
kLast_GrSLType = kSampler2DRect_GrSLType
};
static const int kGrSLTypeCount = kLast_GrSLType + 1;
@ -64,7 +65,7 @@ static const int kGrSLPrecisionCount = kLast_GrSLPrecision + 1;
*/
static inline int GrSLTypeVectorCount(GrSLType type) {
SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1, -1 };
static const int kCounts[] = { -1, 1, 2, 3, 4, -1, -1, -1, -1, -1 };
return kCounts[type];
GR_STATIC_ASSERT(0 == kVoid_GrSLType);
@ -76,6 +77,7 @@ static inline int GrSLTypeVectorCount(GrSLType type) {
GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
GR_STATIC_ASSERT(8 == kSamplerExternal_GrSLType);
GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kCounts) == kGrSLTypeCount);
}
@ -105,8 +107,49 @@ static inline bool GrSLTypeIsFloatType(GrSLType type) {
GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
GR_STATIC_ASSERT(8 == kSamplerExternal_GrSLType);
GR_STATIC_ASSERT(9 == kGrSLTypeCount);
GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
GR_STATIC_ASSERT(10 == kGrSLTypeCount);
}
/** Returns the size in bytes for floating point GrSLTypes. For non floating point type returns 0 */
static inline size_t GrSLTypeSize(GrSLType type) {
SkASSERT(GrSLTypeIsFloatType(type));
static const size_t kSizes[] = {
0, // kVoid_GrSLType
sizeof(float), // kFloat_GrSLType
2 * sizeof(float), // kVec2f_GrSLType
3 * sizeof(float), // kVec3f_GrSLType
4 * sizeof(float), // kVec4f_GrSLType
9 * sizeof(float), // kMat33f_GrSLType
16 * sizeof(float), // kMat44f_GrSLType
0, // kSampler2D_GrSLType
0, // kSamplerExternal_GrSLType
0 // kSampler2DRect_GrSLType
};
return kSizes[type];
GR_STATIC_ASSERT(0 == kVoid_GrSLType);
GR_STATIC_ASSERT(1 == kFloat_GrSLType);
GR_STATIC_ASSERT(2 == kVec2f_GrSLType);
GR_STATIC_ASSERT(3 == kVec3f_GrSLType);
GR_STATIC_ASSERT(4 == kVec4f_GrSLType);
GR_STATIC_ASSERT(5 == kMat33f_GrSLType);
GR_STATIC_ASSERT(6 == kMat44f_GrSLType);
GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
GR_STATIC_ASSERT(8 == kSamplerExternal_GrSLType);
GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
GR_STATIC_ASSERT(10 == kGrSLTypeCount);
}
static inline bool GrSLTypeIsSamplerType(GrSLType type) {
SkASSERT(type >= 0 && type < static_cast<GrSLType>(kGrSLTypeCount));
return type >= 7 && type <= 9;
GR_STATIC_ASSERT(7 == kSampler2D_GrSLType);
GR_STATIC_ASSERT(8 == kSamplerExternal_GrSLType);
GR_STATIC_ASSERT(9 == kSampler2DRect_GrSLType);
}
//////////////////////////////////////////////////////////////////////////////
/**
@ -178,6 +221,7 @@ static inline GrSLType GrVertexAttribTypeToSLType(GrVertexAttribType type) {
switch (type) {
default:
SkFAIL("Unsupported type conversion");
return kVoid_GrSLType;
case kUByte_GrVertexAttribType:
case kFloat_GrVertexAttribType:
return kFloat_GrSLType;
@ -267,6 +311,17 @@ private:
SkIRect fRect;
};
/**
* Indicates the transfer direction for a transfer buffer
*/
enum TransferType {
/** Caller intends to use the buffer to transfer data to the GPU */
kCpuToGpu_TransferType,
/** Caller intends to use the buffer to transfer data from the GPU */
kGpuToCpu_TransferType
};
#ifdef SK_DEBUG
// Takes a pointer to a GrCaps, and will suppress prints if required
#define GrCapsDebugf(caps, ...) \

View File

@ -49,7 +49,7 @@ public:
protected:
// overrides from SkPixelRef
bool onReadPixels(SkBitmap* dst, const SkIRect* subset) override;
bool onReadPixels(SkBitmap* dst, SkColorType, const SkIRect* subset) override;
SkPixelRef* deepCopy(SkColorType, SkColorProfileType,
const SkIRect* subset) override;
void onNotifyPixelsChanged() override;

View File

@ -21,10 +21,16 @@ public:
void getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
GrXPFactory::InvariantBlendedColor*) const override;
/** Because src-over is so common we special case it for performance reasons. If this returns
null then the SimpleSrcOverXP() below should be used. */
static GrXferProcessor* CreateSrcOverXferProcessor(const GrCaps& caps,
const GrPipelineOptimizations& optimizations,
bool hasMixedSamples,
const GrXferProcessor::DstTexture*);
/** This XP implements non-LCD src-over using hw blend with no optimizations. It is returned
by reference because it is global and its ref-cnting methods are not thread safe. */
static const GrXferProcessor& SimpleSrcOverXP();
static inline void SrcOverInvariantBlendedColor(
GrColor inputColor,

View File

@ -17,9 +17,9 @@
* This class is intended for Skia's testing needs and not for general
* use.
*/
class SK_API SkGLContext : public SkRefCnt {
class SK_API SkGLContext : public SkNoncopyable {
public:
~SkGLContext() override;
virtual ~SkGLContext();
bool isValid() const { return NULL != gl(); }
@ -41,6 +41,11 @@ public:
virtual GrEGLImage texture2DToEGLImage(GrGLuint /*texID*/) const { return 0; }
virtual void destroyEGLImage(GrEGLImage) const {}
/** Used for testing GL_TEXTURE_RECTANGLE integration. */
GrGLint createTextureRectangle(int width, int height, GrGLenum internalFormat,
GrGLenum externalFormat, GrGLenum externalType,
GrGLvoid* data);
/**
* Used for testing EGLImage integration. Takes a EGLImage and wraps it in a
* GL_TEXTURE_EXTERNAL_OES.
@ -106,8 +111,6 @@ private:
SkAutoTUnref<const GrGLInterface> fGL;
friend class GLFenceSync; // For onPlatformGetProcAddress.
typedef SkRefCnt INHERITED;
};
/** Creates platform-dependent GL context object

View File

@ -14,7 +14,12 @@ class SK_API SkNullGLContext : public SkGLContext {
public:
~SkNullGLContext() override;
static SkNullGLContext* Create(GrGLStandard);
static SkNullGLContext* Create();
// FIXME: remove once Chromium has been updated.
static SkNullGLContext* Create(GrGLStandard forcedAPI) {
SkASSERT(forcedAPI == kNone_GrGLStandard);
(void)forcedAPI; return Create();
}
class ContextState;

View File

@ -15,18 +15,25 @@
class SkANGLEGLContext : public SkGLContext {
public:
~SkANGLEGLContext() override;
static SkANGLEGLContext* Create(GrGLStandard forcedGpuAPI, bool useGLBackend) {
if (kGL_GrGLStandard == forcedGpuAPI) {
return NULL;
}
SkANGLEGLContext* ctx = new SkANGLEGLContext(useGLBackend);
#ifdef SK_BUILD_FOR_WIN
static SkANGLEGLContext* CreateDirectX() {
SkANGLEGLContext* ctx = new SkANGLEGLContext(false);
if (!ctx->isValid()) {
delete ctx;
return NULL;
}
return ctx;
}
#endif
static SkANGLEGLContext* CreateOpenGL() {
SkANGLEGLContext* ctx = new SkANGLEGLContext(true);
if (!ctx->isValid()) {
delete ctx;
return NULL;
}
return ctx;
}
GrEGLImage texture2DToEGLImage(GrGLuint texID) const override;
void destroyEGLImage(GrEGLImage) const override;
GrGLuint eglImageToExternalTexture(GrEGLImage) const override;

View File

@ -16,10 +16,7 @@ class SkCommandBufferGLContext : public SkGLContext {
public:
~SkCommandBufferGLContext() override;
static SkCommandBufferGLContext* Create(GrGLStandard forcedGpuAPI) {
if (kGL_GrGLStandard == forcedGpuAPI) {
return nullptr;
}
static SkCommandBufferGLContext* Create() {
SkCommandBufferGLContext* ctx = new SkCommandBufferGLContext;
if (!ctx->isValid()) {
delete ctx;

View File

@ -1,174 +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 SkGPipe_DEFINED
#define SkGPipe_DEFINED
#include "SkFlattenable.h"
#include "SkPicture.h"
#include "SkWriter32.h"
class SkCanvas;
// XLib.h might have defined Status already (ugh)
#ifdef Status
#undef Status
#endif
class SkGPipeReader {
public:
SkGPipeReader();
SkGPipeReader(SkCanvas* target);
~SkGPipeReader();
enum Status {
kDone_Status, //!< no more data expected from reader
kEOF_Status, //!< need more data from reader
kError_Status, //!< encountered error
kReadAtom_Status//!< finished reading an atom
};
enum PlaybackFlags {
kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream
kSilent_PlaybackFlag = 0x2, //!< playback without drawing
};
void setCanvas(SkCanvas*);
/**
* Set a function for decoding bitmaps that have encoded data.
*/
void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; }
// data must be 4-byte aligned
// length must be a multiple of 4
Status playback(const void* data, size_t length, uint32_t playbackFlags = 0,
size_t* bytesRead = NULL);
private:
SkCanvas* fCanvas;
class SkGPipeState* fState;
SkPicture::InstallPixelRefProc fProc;
};
///////////////////////////////////////////////////////////////////////////////
class SkGPipeCanvas;
class SkGPipeController {
public:
SkGPipeController() : fCanvas(NULL) {}
virtual ~SkGPipeController();
/**
* Called periodically by the writer, to get a working buffer of RAM to
* write into. The actual size of the block is also returned, and must be
* actual >= minRequest. If NULL is returned, then actual is ignored and
* writing will stop.
*
* The returned block must be 4-byte aligned, and actual must be a
* multiple of 4.
* minRequest will always be a multiple of 4.
*/
virtual void* requestBlock(size_t minRequest, size_t* actual) = 0;
/**
* This is called each time some atomic portion of the data has been
* written to the block (most recently returned by requestBlock()).
* If bytes == 0, then the writer has finished.
*
* bytes will always be a multiple of 4.
*/
virtual void notifyWritten(size_t bytes) = 0;
virtual int numberOfReaders() const { return 1; }
/**
* Release resource references that are held in internal caches.
* This must only be called after the pipe has been completely flushed.
*/
void purgeCaches();
private:
friend class SkGPipeWriter;
void setCanvas(SkGPipeCanvas*);
SkGPipeCanvas* fCanvas;
};
class SkGPipeWriter {
public:
SkGPipeWriter();
~SkGPipeWriter();
bool isRecording() const { return SkToBool(fCanvas); }
enum Flags {
/**
* Tells the writer that the reader will be in a different process, so
* (for example) we cannot put function pointers in the stream.
*/
kCrossProcess_Flag = 1 << 0,
/**
* Only meaningful if kCrossProcess_Flag is set. Tells the writer that
* in spite of being cross process, it will have shared address space
* with the reader, so the two can share large objects (like SkBitmaps).
*/
kSharedAddressSpace_Flag = 1 << 1,
/**
* Tells the writer that there will be multiple threads reading the stream
* simultaneously.
*/
kSimultaneousReaders_Flag = 1 << 2,
};
SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0,
uint32_t width = kDefaultRecordingCanvasSize,
uint32_t height = kDefaultRecordingCanvasSize);
// called in destructor, but can be called sooner once you know there
// should be no more drawing calls made into the recording canvas.
void endRecording();
/**
* Tells the writer to commit all recorded draw commands to the
* controller immediately.
* @param detachCurrentBlock Set to true to request that the next draw
* command be recorded in a new block.
*/
void flushRecording(bool detachCurrentBlock);
/**
* Return the amount of bytes being used for recording. Note that this
* does not include the amount of storage written to the stream, which is
* controlled by the SkGPipeController.
* Currently only returns the amount used for SkBitmaps, since they are
* potentially unbounded (if the client is not calling playback).
*/
size_t storageAllocatedForRecording() const;
/**
* Attempt to reduce the storage allocated for recording by evicting
* cache resources.
* @param bytesToFree minimum number of bytes that should be attempted to
* be freed.
* @return number of bytes actually freed.
*/
size_t freeMemoryIfPossible(size_t bytesToFree);
private:
enum {
kDefaultRecordingCanvasSize = 32767,
};
SkGPipeCanvas* fCanvas;
SkWriter32 fWriter;
};
#endif

View File

@ -43,6 +43,8 @@ public:
* The caller must call unref() on the returned object.
* Never returns NULL; will return an empty set if the name is not found.
*
* Passing |nullptr| as the parameter will return the default system font.
*
* It is possible that this will return a style set not accessible from
* createStyleSet(int) due to hidden or auto-activated fonts.
*/
@ -54,6 +56,9 @@ public:
* object. Will never return NULL, as it will return the default font if
* no matching font is found.
*
* Passing |nullptr| as the parameter for |familyName| will return the
* default system font.
*
* It is possible that this will return a style set not accessible from
* createStyleSet(int) or matchFamily(const char[]) due to hidden or
* auto-activated fonts.
@ -68,6 +73,9 @@ public:
* Will return NULL if no family can be found for the character
* in the system fallback.
*
* Passing |nullptr| as the parameter for |familyName| will return the
* default system font.
*
* bcp47[0] is the least significant fallback, bcp47[bcp47Count-1] is the
* most significant. If no specified bcp47 codes match, any font with the
* requested character will be matched.

View File

@ -0,0 +1,116 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrAuditTrail_DEFINED
#define GrAuditTrail_DEFINED
#include "GrConfig.h"
#include "SkRect.h"
#include "SkString.h"
#include "SkTArray.h"
/*
* GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
* to json.
*/
class GrAuditTrail {
public:
GrAuditTrail() : fUniqueID(0) {}
class AutoFrame {
public:
AutoFrame(GrAuditTrail* auditTrail, const char* name)
: fAuditTrail(auditTrail) {
if (GR_BATCH_DEBUGGING_OUTPUT) {
fAuditTrail->pushFrame(name);
}
}
~AutoFrame() {
if (GR_BATCH_DEBUGGING_OUTPUT) {
fAuditTrail->popFrame();
}
}
private:
GrAuditTrail* fAuditTrail;
};
void pushFrame(const char* name) {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
Frame* frame = new Frame;
if (fStack.empty()) {
fFrames.emplace_back(frame);
} else {
fStack.back()->fChildren.emplace_back(frame);
}
frame->fUniqueID = fUniqueID++;
frame->fName = name;
fStack.push_back(frame);
}
void popFrame() {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
fStack.pop_back();
}
void addBatch(const char* name, const SkRect& bounds) {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && !fStack.empty());
Batch* batch = new Batch;
fStack.back()->fChildren.emplace_back(batch);
batch->fName = name;
batch->fBounds = bounds;
}
SkString toJson() const;
void reset() { SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && fStack.empty()); fFrames.reset(); }
private:
// TODO if performance becomes an issue, we can move to using SkVarAlloc
struct Event {
virtual ~Event() {}
virtual SkString toJson() const=0;
const char* fName;
uint64_t fUniqueID;
};
typedef SkTArray<SkAutoTDelete<Event>, true> FrameArray;
struct Frame : public Event {
SkString toJson() const override;
FrameArray fChildren;
};
struct Batch : public Event {
SkString toJson() const override;
SkRect fBounds;
};
static void JsonifyTArray(SkString* json, const char* name, const FrameArray& array);
FrameArray fFrames;
SkTArray<Frame*> fStack;
uint64_t fUniqueID;
};
#define GR_AUDIT_TRAIL_INVOKE_GUARD(invoke, ...) \
if (GR_BATCH_DEBUGGING_OUTPUT) { \
invoke(__VA_ARGS__); \
}
#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail->reset);
#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail->addBatch, batchname, bounds);
#endif

View File

@ -0,0 +1,55 @@
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrSingleOwner_DEFINED
#define GrSingleOwner_DEFINED
#include "SkTypes.h"
#ifdef SK_DEBUG
#include "SkMutex.h"
#include "SkThreadID.h"
// This is a debug tool to verify an object is only being used from one thread at a time.
class GrSingleOwner {
public:
GrSingleOwner() : fOwner(kIllegalThreadID), fReentranceCount(0) {}
struct AutoEnforce {
AutoEnforce(GrSingleOwner* so) : fSO(so) { fSO->enter(); }
~AutoEnforce() { fSO->exit(); }
GrSingleOwner* fSO;
};
private:
void enter() {
SkAutoMutexAcquire lock(fMutex);
SkThreadID self = SkGetThreadID();
SkASSERT(fOwner == self || fOwner == kIllegalThreadID);
fReentranceCount++;
fOwner = self;
}
void exit() {
SkAutoMutexAcquire lock(fMutex);
SkASSERT(fOwner == SkGetThreadID());
fReentranceCount--;
if (fReentranceCount == 0) {
fOwner = kIllegalThreadID;
}
}
SkMutex fMutex;
SkThreadID fOwner; // guarded by fMutex
int fReentranceCount; // guarded by fMutex
};
#else
class GrSingleOwner {}; // Provide a dummy implementation so we can pass pointers to constructors
#endif
#endif

View File

@ -12,7 +12,7 @@
#include "SkTypes.h"
#include <math.h>
#include <cmath>
#include <float.h>
// For _POSIX_VERSION
@ -95,9 +95,9 @@ static inline float sk_float_copysign(float x, float y) {
return (bits << 1) == (0xFF << 24);
}
#else
#define sk_float_isfinite(x) isfinite(x)
#define sk_float_isnan(x) isnan(x)
#define sk_float_isinf(x) isinf(x)
#define sk_float_isfinite(x) std::isfinite(x)
#define sk_float_isnan(x) std::isnan(x)
#define sk_float_isinf(x) std::isinf(x)
#endif
#define sk_double_isnan(a) sk_float_isnan(a)

View File

@ -10,6 +10,7 @@
#include "SkCanvas.h"
#include "SkDrawable.h"
#include "SkImageFilter.h"
#include "SkMatrix.h"
#include "SkPath.h"
#include "SkPicture.h"
@ -63,7 +64,6 @@ namespace SkRecords {
M(DrawTextOnPath) \
M(DrawRRect) \
M(DrawRect) \
M(DrawSprite) \
M(DrawTextBlob) \
M(DrawAtlas) \
M(DrawVertices)
@ -198,7 +198,8 @@ RECORD(Save, 0);
RECORD(SaveLayer, 0,
Optional<SkRect> bounds;
Optional<SkPaint> paint;
SkCanvas::SaveFlags flags);
RefBox<const SkImageFilter> backdrop;
SkCanvas::SaveLayerFlags saveLayerFlags);
RECORD(SetMatrix, 0,
TypedMatrix matrix);
@ -315,11 +316,6 @@ RECORD(DrawRRect, kDraw_Tag,
RECORD(DrawRect, kDraw_Tag,
SkPaint paint;
SkRect rect);
RECORD(DrawSprite, kDraw_Tag|kHasImage_Tag,
Optional<SkPaint> paint;
ImmutableBitmap bitmap;
int left;
int top);
RECORD(DrawText, kDraw_Tag|kHasText_Tag,
SkPaint paint;
PODArray<char> text;

View File

@ -5,9 +5,10 @@
* found in the LICENSE file.
*
*
* This header provides some of the helpers (std::integral_constant) and
* type transformations (std::conditional) which will become available with
* C++11 in the type_traits header.
* This header provides some of the helpers (like std::enable_if_t) which will
* become available with C++14 in the type_traits header (in the skstd
* namespace). This header also provides several Skia specific additions such
* as SK_WHEN and the sknonstd namespace.
*/
#ifndef SkTLogic_DEFINED
@ -17,147 +18,98 @@
#include <stddef.h>
#include <stdint.h>
#include <utility>
#if SKIA_IMPLEMENTATION
#include <algorithm>
#endif
#ifdef MOZ_SKIA
#include "mozilla/Move.h"
#include "mozilla/TypeTraits.h"
#if SKIA_IMPLEMENTATION
#include "mozilla/Function.h"
#endif
namespace std {
using mozilla::Forward;
#define forward Forward
#if SKIA_IMPLEMENTATION
using mozilla::IntegralConstant;
using mozilla::IsEmpty;
using mozilla::FalseType;
using mozilla::TrueType;
#define integral_constant IntegralConstant
#define is_empty IsEmpty
#define false_type FalseType
#define true_type TrueType
using mozilla::Function;
#define function Function
#endif
}
namespace skstd {
using nullptr_t = decltype(nullptr);
template <bool B> using bool_constant = mozilla::IntegralConstant<bool, B>;
template <typename T, T v> struct integral_constant {
static const/*expr*/ T value = v;
using value_type = T;
using type = integral_constant<T, v>;
//constexpr operator value_type() const noexcept { return value; }
//constexpr value_type operator()() const noexcept { return value; }
};
template <bool B, typename T, typename F> using conditional_t = typename mozilla::Conditional<B, T, F>::Type;
template <bool B, typename T = void> using enable_if_t = typename mozilla::EnableIf<B, T>::Type;
template <bool B> using bool_constant = integral_constant<bool, B>;
}
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
#else /* !MOZ_SKIA */
template <bool B, typename T, typename F> struct conditional { using type = T; };
template <typename T, typename F> struct conditional<false, T, F> { using type = F; };
template <bool B, typename T, typename F> using conditional_t = typename conditional<B, T, F>::type;
#include <type_traits>
#include <functional>
template <bool B, typename T = void> struct enable_if { using type = T; };
template <typename T> struct enable_if<false, T> {};
template <bool B, typename T = void> using enable_if_t = typename enable_if<B, T>::type;
namespace skstd {
template <typename T> struct remove_const { using type = T; };
template <typename T> struct remove_const<const T> { using type = T; };
template <typename T> using remove_const_t = typename remove_const<T>::type;
template <bool B> using bool_constant = std::integral_constant<bool, B>;
template <typename T> struct remove_volatile { using type = T; };
template <typename T> struct remove_volatile<volatile T> { using type = T; };
template <typename T> using remove_volatile_t = typename remove_volatile<T>::type;
template <bool B, typename T, typename F> using conditional_t = typename std::conditional<B, T, F>::type;
template <bool B, typename T = void> using enable_if_t = typename std::enable_if<B, T>::type;
template <typename T> struct remove_cv { using type = remove_volatile_t<remove_const_t<T>>; };
template <typename T> using remove_cv_t = typename remove_cv<T>::type;
template <typename T> struct remove_reference { using type = T; };
template <typename T> struct remove_reference<T&> { using type = T; };
template <typename T> struct remove_reference<T&&> { using type = T; };
template <typename T> using remove_reference_t = typename remove_reference<T>::type;
template <typename T> struct remove_extent { using type = T; };
template <typename T> struct remove_extent<T[]> { using type = T; };
template <typename T, size_t N> struct remove_extent<T[N]> { using type = T;};
template <typename T> using remove_extent_t = typename remove_extent<T>::type;
template <typename T, typename U> struct is_same : false_type {};
template <typename T> struct is_same<T, T> : true_type {};
template <typename T> struct is_void : is_same<void, remove_cv_t<T>> {};
template <typename T> struct is_const : false_type {};
template <typename T> struct is_const<const T> : true_type {};
template <typename T> struct is_volatile : false_type {};
template <typename T> struct is_volatile<volatile T> : true_type {};
template <typename T> struct is_pointer_detector : false_type {};
template <typename T> struct is_pointer_detector<T*> : true_type {};
template <typename T> struct is_pointer : is_pointer_detector<remove_cv_t<T>> {};
template <typename T> struct is_reference : false_type {};
template <typename T> struct is_reference<T&> : true_type {};
template <typename T> struct is_reference<T&&> : true_type {};
template <typename T> struct is_lvalue_reference : false_type {};
template <typename T> struct is_lvalue_reference<T&> : true_type {};
template <typename T> struct is_rvalue_reference : false_type {};
template <typename T> struct is_rvalue_reference<T&&> : true_type {};
template <typename T> struct is_class_detector {
using yes_type = uint8_t;
using no_type = uint16_t;
template <typename U> static yes_type clazz(int U::*);
template <typename U> static no_type clazz(...);
static const/*expr*/ bool value = sizeof(clazz<T>(0)) == sizeof(yes_type) /*&& !is_union<T>::value*/;
};
template <typename T> struct is_class : bool_constant<is_class_detector<T>::value> {};
template <typename T, bool = is_class<T>::value> struct is_empty_detector {
struct Derived : public T { char unused; };
static const/*expr*/ bool value = sizeof(Derived) == sizeof(char);
};
template <typename T> struct is_empty_detector<T, false> {
static const/*expr*/ bool value = false;
};
template <typename T> struct is_empty : bool_constant<is_empty_detector<T>::value> {};
template <typename T> struct is_array : false_type {};
template <typename T> struct is_array<T[]> : true_type {};
template <typename T, size_t N> struct is_array<T[N]> : true_type {};
template <typename T> using remove_const_t = typename std::remove_const<T>::type;
template <typename T> using remove_volatile_t = typename std::remove_volatile<T>::type;
template <typename T> using remove_cv_t = typename std::remove_cv<T>::type;
template <typename T> using remove_pointer_t = typename std::remove_pointer<T>::type;
template <typename T> using remove_reference_t = typename std::remove_reference<T>::type;
template <typename T> using remove_extent_t = typename std::remove_extent<T>::type;
// template<typename R, typename... Args> struct is_function<
// R [calling-convention] (Args...[, ...]) [const] [volatile] [&|&&]> : true_type {};
// R [calling-convention] (Args...[, ...]) [const] [volatile] [&|&&]> : std::true_type {};
// The cv and ref-qualified versions are strange types we're currently avoiding, so not supported.
// These aren't supported in msvc either until vs2015u2.
// On all platforms, variadic functions only exist in the c calling convention.
template <typename> struct is_function : false_type { };
// mcvc 2013 introduced __vectorcall, but it wan't until 2015 that it was added to is_function.
template <typename> struct is_function : std::false_type {};
#if !defined(SK_BUILD_FOR_WIN)
template <typename R, typename... Args> struct is_function<R(Args...)> : true_type {};
template <typename R, typename... Args> struct is_function<R(Args...)> : std::true_type {};
#else
template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : true_type {};
template <typename R, typename... Args> struct is_function<R __cdecl (Args...)> : std::true_type {};
#if defined(_M_IX86)
template <typename R, typename... Args> struct is_function<R __stdcall (Args...)> : true_type {};
template <typename R, typename... Args> struct is_function<R __fastcall (Args...)> : true_type {};
template <typename R, typename... Args> struct is_function<R __stdcall (Args...)> : std::true_type {};
template <typename R, typename... Args> struct is_function<R __fastcall (Args...)> : std::true_type {};
#endif
#if defined(_MSC_VER) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : true_type {};
template <typename R, typename... Args> struct is_function<R __vectorcall (Args...)> : std::true_type {};
#endif
#endif
template <typename R, typename... Args> struct is_function<R(Args..., ...)> : true_type {};
template <typename R, typename... Args> struct is_function<R(Args..., ...)> : std::true_type {};
template <typename T> struct add_const { using type = const T; };
template <typename T> using add_const_t = typename add_const<T>::type;
template <typename T> using add_const_t = typename std::add_const<T>::type;
template <typename T> using add_volatile_t = typename std::add_volatile<T>::type;
template <typename T> using add_cv_t = typename std::add_cv<T>::type;
template <typename T> using add_pointer_t = typename std::add_pointer<T>::type;
template <typename T> using add_lvalue_reference_t = typename std::add_lvalue_reference<T>::type;
template <typename T> struct add_volatile { using type = volatile T; };
template <typename T> using add_volatile_t = typename add_volatile<T>::type;
template <typename T> struct add_cv { using type = add_volatile_t<add_const_t<T>>; };
template <typename T> using add_cv_t = typename add_cv<T>::type;
template <typename T> struct add_pointer { using type = remove_reference_t<T>*; };
template <typename T> using add_pointer_t = typename add_pointer<T>::type;
template <typename T, bool=is_void<T>::value> struct add_lvalue_reference_init { using type = T; };
template <typename T> struct add_lvalue_reference_init<T, false> { using type = T&; };
template <typename T> struct add_lvalue_reference : add_lvalue_reference_init<T> { };
template <typename T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type;
template <typename T, bool=is_void<T>::value> struct add_rvalue_reference_init { using type = T; };
template <typename T> struct add_rvalue_reference_init<T, false> { using type = T&&; };
template <typename T> struct add_rvalue_reference : add_rvalue_reference_init<T> {};
template <typename T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type;
/* This is 'just' a forward declaration. */
template <typename T> add_rvalue_reference_t<T> declval() /*noexcept*/;
template <typename S, typename D, bool=is_void<S>::value||is_function<D>::value||is_array<D>::value>
template <typename S, typename D,
bool=std::is_void<S>::value || is_function<D>::value || std::is_array<D>::value>
struct is_convertible_detector {
static const/*expr*/ bool value = is_void<D>::value;
static const/*expr*/ bool value = std::is_void<D>::value;
};
template <typename S, typename D> struct is_convertible_detector<S, D, false> {
using yes_type = uint8_t;
@ -166,22 +118,16 @@ template <typename S, typename D> struct is_convertible_detector<S, D, false> {
template <typename To> static void param_convertable_to(To);
template <typename From, typename To>
static decltype(param_convertable_to<To>(declval<From>()), yes_type()) convertible(int);
static decltype(param_convertable_to<To>(std::declval<From>()), yes_type()) convertible(int);
template <typename, typename> static no_type convertible(...);
static const/*expr*/ bool value = sizeof(convertible<S, D>(0)) == sizeof(yes_type);
};
// std::is_convertable is known to be broken (not work with incomplete types) in Android clang NDK.
// This is currently what prevents us from using std::unique_ptr.
template<typename S, typename D> struct is_convertible
: bool_constant<is_convertible_detector<S, D>::value> { };
template <typename T> struct decay {
using U = remove_reference_t<T>;
using type = conditional_t<is_array<U>::value,
remove_extent_t<U>*,
conditional_t<is_function<U>::value, add_pointer_t<U>, remove_cv_t<U>>>;
};
template <typename T> using decay_t = typename decay<T>::type;
: bool_constant<is_convertible_detector<S, D>::value> {};
} // namespace skstd
@ -193,12 +139,12 @@ namespace sknonstd {
// std::experimental::propagate_const already exists for other purposes in TSv2.
// These also follow the <dest, source> pattern used by boost.
template <typename D, typename S> struct copy_const {
using type = skstd::conditional_t<skstd::is_const<S>::value, skstd::add_const_t<D>, D>;
using type = skstd::conditional_t<std::is_const<S>::value, skstd::add_const_t<D>, D>;
};
template <typename D, typename S> using copy_const_t = typename copy_const<D, S>::type;
template <typename D, typename S> struct copy_volatile {
using type = skstd::conditional_t<skstd::is_volatile<S>::value, skstd::add_volatile_t<D>, D>;
using type = skstd::conditional_t<std::is_volatile<S>::value, skstd::add_volatile_t<D>, D>;
};
template <typename D, typename S> using copy_volatile_t = typename copy_volatile<D, S>::type;
@ -219,6 +165,8 @@ template <typename D, typename S> using same_cv_t = typename same_cv<D, S>::type
} // namespace sknonstd
#endif /* MOZ_SKIA */
// Just a pithier wrapper for enable_if_t.
#define SK_WHEN(condition, T) skstd::enable_if_t<!!(condition), T>

View File

@ -14,7 +14,6 @@
#include "SkTLogic.h"
#include "SkTypes.h"
#include "SkUniquePtr.h"
#include "SkUtility.h"
#include <limits.h>
#include <new>
@ -43,7 +42,7 @@ template <typename D, typename S> static D* SkTAfter(S* ptr, size_t count = 1) {
template <typename D, typename S> static D* SkTAddOffset(S* ptr, size_t byteOffset) {
// The intermediate char* has the same cv-ness as D as this produces better error messages.
// This relies on the fact that reinterpret_cast can add constness, but cannot remove it.
return reinterpret_cast<D*>(reinterpret_cast<sknonstd::same_cv_t<char, D>*>(ptr) + byteOffset);
return reinterpret_cast<D*>((char*)(ptr) + byteOffset);
}
template <typename R, typename T, R (*P)(T*)> struct SkFunctionWrapper {
@ -272,9 +271,10 @@ public:
}
/** Resize the memory area pointed to by the current ptr without preserving contents. */
void reset(size_t count) {
T* reset(size_t count) {
sk_free(fPtr);
fPtr = (T*)sk_malloc_flags(count * sizeof(T), SK_MALLOC_THROW);
return fPtr;
}
T* get() const { return fPtr; }
@ -295,6 +295,13 @@ public:
return fPtr[index];
}
/**
* Releases the block back to the heap
*/
void free() {
this->reset(0);
}
/**
* Transfer ownership of the ptr to the caller, setting the internal
* pointer to NULL. Note that this differs from get(), which also returns

View File

@ -9,8 +9,19 @@
#define SkUniquePtr_DEFINED
#include "SkTLogic.h"
#include "SkUtility.h"
#include <cstddef>
#include <utility>
#ifdef MOZ_SKIA
#include "mozilla/UniquePtr.h"
namespace skstd {
using mozilla::DefaultDelete;
using mozilla::UniquePtr;
#define default_delete DefaultDelete
#define unique_ptr UniquePtr
}
#else
namespace skstd {
template <typename T> struct default_delete {
@ -47,11 +58,11 @@ public:
using deleter_type = D;
private:
template <typename B, bool>
template <typename B, bool = std::is_empty<B>::value /*&& !is_final<B>::value*/>
struct compressed_base : private B {
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : B(b) {}
/*constexpr*/ compressed_base(const B&& b) : B(move(b)) {}
/*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return *this; }
/*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
void swap(compressed_base&) /*noexcept*/ { }
@ -61,33 +72,31 @@ private:
B fb;
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : fb(b) {}
/*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {}
/*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return fb; }
/*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
};
using compressed_deleter_type = compressed_base<deleter_type, is_empty<deleter_type>::value>;
struct compressed_data : private compressed_deleter_type {
struct compressed_data : private compressed_base<deleter_type> {
pointer fPtr;
/*constexpr*/ compressed_data() : compressed_deleter_type(), fPtr() {}
/*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr() {}
/*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
: compressed_deleter_type(d), fPtr(ptr) {}
: compressed_base<deleter_type>(d), fPtr(ptr) {}
template <typename U1, typename U2, typename = enable_if_t<
is_convertible<U1, pointer>::value && is_convertible<U2, deleter_type>::value
>> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
: compressed_deleter_type(skstd::forward<U2>(d)), fPtr(skstd::forward<U1>(ptr)) {}
: compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forward<U1>(ptr)) {}
/*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
/*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fPtr; }
/*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
return compressed_deleter_type::get();
return compressed_base<deleter_type>::get();
}
/*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
return compressed_deleter_type::get();
return compressed_base<deleter_type>::get();
}
void swap(compressed_data& that) /*noexcept*/ {
compressed_deleter_type::swap(static_cast<compressed_deleter_type>(that));
compressed_base<deleter_type>::swap(static_cast<compressed_base<deleter_type>>(that));
SkTSwap(fPtr, that.fPtr);
}
};
@ -95,38 +104,41 @@ private:
public:
/*constexpr*/ unique_ptr() /*noexcept*/ : data() {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
static_assert(!std::is_pointer<deleter_type>::value, "Deleter nullptr function pointer!");
}
/*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { }
/*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
static_assert(!std::is_pointer<deleter_type>::value, "Deleter nullptr function pointer!");
}
unique_ptr(pointer ptr,
conditional_t<is_reference<deleter_type>::value, deleter_type,const deleter_type&> d)
conditional_t<std::is_reference<deleter_type>::value,
deleter_type, const deleter_type&> d)
/*noexcept*/ : data(ptr, d)
{}
unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
: data(move(ptr), move(d))
: data(std::move(ptr), std::move(d))
{
static_assert(!is_reference<deleter_type>::value,
static_assert(!std::is_reference<deleter_type>::value,
"Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
}
unique_ptr(unique_ptr&& that) /*noexcept*/
: data(that.release(), forward<deleter_type>(that.get_deleter()))
: data(that.release(), std::forward<deleter_type>(that.get_deleter()))
{}
template <typename U, typename ThatD, typename = enable_if_t<
is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value &&
!is_array<U>::value &&
conditional_t<is_reference<D>::value, is_same<ThatD, D>, is_convertible<ThatD, D>>::value>>
!std::is_array<U>::value &&
conditional_t<std::is_reference<D>::value,
std::is_same<ThatD, D>,
is_convertible<ThatD, D>>::value>>
unique_ptr(unique_ptr<U, ThatD>&& that) /*noexcept*/
: data(that.release(), forward<ThatD>(that.get_deleter()))
: data(that.release(), std::forward<ThatD>(that.get_deleter()))
{}
~unique_ptr() /*noexcept*/ {
@ -139,20 +151,20 @@ public:
unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
reset(that.release());
get_deleter() = forward<deleter_type>(that.get_deleter());
get_deleter() = std::forward<deleter_type>(that.get_deleter());
return *this;
}
template <typename U, typename ThatD> enable_if_t<
is_convertible<typename unique_ptr<U, ThatD>::pointer, pointer>::value &&
!is_array<U>::value,
!std::is_array<U>::value,
unique_ptr&> operator=(unique_ptr<U, ThatD>&& that) /*noexcept*/ {
reset(that.release());
get_deleter() = forward<ThatD>(that.get_deleter());
get_deleter() = std::forward<ThatD>(that.get_deleter());
return *this;
}
unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ {
unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
reset();
return *this;
}
@ -219,11 +231,11 @@ public:
using deleter_type = D;
private:
template <typename B, bool>
template <typename B, bool = std::is_empty<B>::value /*&& !is_final<B>::value*/>
struct compressed_base : private B {
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : B(b) {}
/*constexpr*/ compressed_base(const B&& b) : B(move(b)) {}
/*constexpr*/ compressed_base(B&& b) : B(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return *this; }
/*constexpr*/ B const& get() const /*noexcept*/ { return *this; }
void swap(compressed_base&) /*noexcept*/ { }
@ -233,33 +245,31 @@ private:
B fb;
/*constexpr*/ compressed_base() : B() {}
/*constexpr*/ compressed_base(const B& b) : fb(b) {}
/*constexpr*/ compressed_base(const B&& b) : fb(move(b)) {}
/*constexpr*/ compressed_base(B&& b) : fb(std::move(b)) {}
/*constexpr*/ B& get() /*noexcept*/ { return fb; }
/*constexpr*/ B const& get() const /*noexcept*/ { return fb; }
void swap(compressed_base& that) /*noexcept*/ { SkTSwap(fb, that.fB); }
};
using compressed_deleter_type = compressed_base<deleter_type, is_empty<deleter_type>::value>;
struct compressed_data : private compressed_deleter_type {
struct compressed_data : private compressed_base<deleter_type> {
pointer fPtr;
/*constexpr*/ compressed_data() : compressed_deleter_type(), fPtr() {}
/*constexpr*/ compressed_data() : compressed_base<deleter_type>(), fPtr() {}
/*constexpr*/ compressed_data(const pointer& ptr, const deleter_type& d)
: compressed_deleter_type(d), fPtr(ptr) {}
: compressed_base<deleter_type>(d), fPtr(ptr) {}
template <typename U1, typename U2, typename = enable_if_t<
is_convertible<U1, pointer>::value && is_convertible<U2, deleter_type>::value
>> /*constexpr*/ compressed_data(U1&& ptr, U2&& d)
: compressed_deleter_type(skstd::forward<U2>(d)), fPtr(skstd::forward<U1>(ptr)) {}
: compressed_base<deleter_type>(std::forward<U2>(d)), fPtr(std::forward<U1>(ptr)) {}
/*constexpr*/ pointer& getPointer() /*noexcept*/ { return fPtr; }
/*constexpr*/ pointer const& getPointer() const /*noexcept*/ { return fPtr; }
/*constexpr*/ deleter_type& getDeleter() /*noexcept*/ {
return compressed_deleter_type::get();
return compressed_base<deleter_type>::get();
}
/*constexpr*/ deleter_type const& getDeleter() const /*noexcept*/ {
return compressed_deleter_type::get();
return compressed_base<deleter_type>::get();
}
void swap(compressed_data& that) /*noexcept*/ {
compressed_deleter_type::swap(static_cast<compressed_deleter_type>(that));
compressed_base<deleter_type>::swap(static_cast<compressed_base<deleter_type>>(that));
SkTSwap(fPtr, that.fPtr);
}
};
@ -267,29 +277,30 @@ private:
public:
/*constexpr*/ unique_ptr() /*noexcept*/ : data() {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
static_assert(!std::is_pointer<deleter_type>::value, "Deleter nullptr function pointer!");
}
/*constexpr*/ unique_ptr(skstd::nullptr_t) /*noexcept*/ : unique_ptr() { }
/*constexpr*/ unique_ptr(std::nullptr_t) /*noexcept*/ : unique_ptr() { }
explicit unique_ptr(pointer ptr) /*noexcept*/ : data(ptr, deleter_type()) {
static_assert(!is_pointer<deleter_type>::value, "Deleter is nullptr function pointer!");
static_assert(!std::is_pointer<deleter_type>::value, "Deleter nullptr function pointer!");
}
unique_ptr(pointer ptr,
conditional_t<is_reference<deleter_type>::value, deleter_type,const deleter_type&> d)
conditional_t<std::is_reference<deleter_type>::value,
deleter_type, const deleter_type&> d)
/*noexcept*/ : data(ptr, d)
{}
unique_ptr(pointer ptr, remove_reference_t<deleter_type>&& d) /*noexcept*/
: data(move(ptr), move(d))
: data(std::move(ptr), std::move(d))
{
static_assert(!is_reference<deleter_type>::value,
static_assert(!std::is_reference<deleter_type>::value,
"Binding an rvalue reference deleter as an lvalue reference deleter is not allowed.");
}
unique_ptr(unique_ptr&& that) /*noexcept*/
: data(that.release(), forward<deleter_type>(that.get_deleter()))
: data(that.release(), std::forward<deleter_type>(that.get_deleter()))
{}
~unique_ptr() {
@ -302,11 +313,11 @@ public:
unique_ptr& operator=(unique_ptr&& that) /*noexcept*/ {
reset(that.release());
get_deleter() = forward<deleter_type>(that.get_deleter());
get_deleter() = std::forward<deleter_type>(that.get_deleter());
return *this;
}
unique_ptr& operator=(skstd::nullptr_t) /*noexcept*/ {
unique_ptr& operator=(std::nullptr_t) /*noexcept*/ {
reset();
return *this;
}
@ -367,13 +378,13 @@ inline bool operator==(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b)
}
template <typename T, typename D>
inline bool operator==(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ {
inline bool operator==(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
//return !a;
return !a.is_attached();
}
template <typename T, typename D>
inline bool operator==(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
inline bool operator==(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
//return !b;
return !b.is_attached();
}
@ -384,17 +395,18 @@ inline bool operator!=(const unique_ptr<T, D>& a, const unique_ptr<U, ThatD>& b)
}
template <typename T, typename D>
inline bool operator!=(const unique_ptr<T, D>& a, skstd::nullptr_t) /*noexcept*/ {
inline bool operator!=(const unique_ptr<T, D>& a, std::nullptr_t) /*noexcept*/ {
//return (bool)a;
return a.is_attached();
}
template <typename T, typename D>
inline bool operator!=(skstd::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
inline bool operator!=(std::nullptr_t, const unique_ptr<T, D>& b) /*noexcept*/ {
//return (bool)b;
return b.is_attached();
}
} // namespace skstd
#endif
#endif

View File

@ -1,32 +0,0 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkUtility_DEFINED
#define SkUtility_DEFINED
#include "SkTLogic.h"
namespace skstd {
template <typename T> inline remove_reference_t<T>&& move(T&& t) {
return static_cast<remove_reference_t<T>&&>(t);
}
template <typename T> inline T&& forward(remove_reference_t<T>& t) /*noexcept*/ {
return static_cast<T&&>(t);
}
template <typename T> inline T&& forward(remove_reference_t<T>&& t) /*noexcept*/ {
static_assert(!is_lvalue_reference<T>::value,
"Forwarding an rvalue reference as an lvalue reference is not allowed.");
return static_cast<T&&>(t);
}
template <typename T> add_rvalue_reference_t<T> declval();
} // namespace skstd
#endif

View File

@ -11,7 +11,7 @@
#define SkSVGParser_DEFINED
#include "SkMatrix.h"
#include "SkTDict.h"
#include "../private/SkTDict.h"
#include "SkSVGPaintState.h"
#include "SkSVGTypes.h"
#include "SkStream.h"

View File

@ -1,22 +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 SkCubicInterval_DEFINED
#define SkCubicInterval_DEFINED
#include "SkPoint.h"
SkScalar SkEvalCubicInterval(SkScalar x1, SkScalar y1,
SkScalar x2, SkScalar y2,
SkScalar unitX);
static inline SkScalar SkEvalCubicInterval(const SkPoint pts[2], SkScalar x) {
return SkEvalCubicInterval(pts[0].fX, pts[0].fY,
pts[1].fX, pts[1].fY, x);
}
#endif

View File

@ -1,71 +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 SkCullPoints_DEFINED
#define SkCullPoints_DEFINED
#include "SkRect.h"
class SkCullPoints {
public:
SkCullPoints();
SkCullPoints(const SkIRect& r);
void reset(const SkIRect& r);
/** Start a contour at (x,y). Follow this with call(s) to lineTo(...)
*/
void moveTo(int x, int y);
enum LineToResult {
kNo_Result, //!< line segment was completely clipped out
kLineTo_Result, //!< path.lineTo(pts[1]);
kMoveToLineTo_Result //!< path.moveTo(pts[0]); path.lineTo(pts[1]);
};
/** Connect a line to the previous call to lineTo (or moveTo).
*/
LineToResult lineTo(int x, int y, SkIPoint pts[2]);
private:
SkIRect fR; // the caller's rectangle
SkIPoint fAsQuad[4]; // cache of fR as 4 points
SkIPoint fPrevPt; // private state
LineToResult fPrevResult; // private state
bool sect_test(int x0, int y0, int x1, int y1) const;
};
/////////////////////////////////////////////////////////////////////////////////
class SkPath;
/** \class SkCullPointsPath
Similar to SkCullPoints, but this class handles the return values
from lineTo, and automatically builds a SkPath with the result(s).
*/
class SkCullPointsPath {
public:
SkCullPointsPath();
SkCullPointsPath(const SkIRect& r, SkPath* dst);
void reset(const SkIRect& r, SkPath* dst);
void moveTo(int x, int y);
void lineTo(int x, int y);
private:
SkCullPoints fCP;
SkPath* fPath;
};
bool SkHitTestPath(const SkPath&, SkRect& target, bool hires);
bool SkHitTestPath(const SkPath&, SkScalar x, SkScalar y, bool hires);
#endif

View File

@ -73,7 +73,7 @@ public:
protected:
void willSave() override;
SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
void didConcat(const SkMatrix&) override;
@ -108,7 +108,6 @@ protected:
const SkPaint*, SrcRectConstraint) override;
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*) override;
void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) override;
void onDrawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,

View File

@ -59,7 +59,7 @@ public:
fFlags = SkToU8((fFlags & ~kReset) | (int)reset);
}
Result timeToT(SkMSec time, SkScalar* T, int* index, SkBool* exact) const;
Result timeToT(SkMSec time, SkScalar* T, int* index, bool* exact) const;
protected:
enum Flags {
@ -121,8 +121,15 @@ private:
typedef SkInterpolatorBase INHERITED;
};
/** Given all the parameters are [0...1], apply the cubic specified by (0,0)
(bx,by) (cx,cy) (1,1) to value, returning the answer, also [0...1].
/** Interpolate a cubic curve, typically to provide an ease-in ease-out transition.
All the parameters are in the range of [0...1].
The input value is treated as the x-coordinate of the cubic.
The output value is the y-coordinate on the cubic at the x-coordinate.
@param value The x-coordinate pinned between [0..1].
@param bx,by,cx,cy The cubic control points where the cubic is specified
as (0,0) (bx,by) (cx,cy) (1,1)
@return the corresponding y-coordinate value, from [0..1].
*/
SkScalar SkUnitCubicInterp(SkScalar value, SkScalar bx, SkScalar by,
SkScalar cx, SkScalar cy);

View File

@ -22,7 +22,7 @@ public:
protected:
void willSave() override;
SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
void didConcat(const SkMatrix&) override;
@ -54,7 +54,6 @@ protected:
const SkPaint*, SrcRectConstraint) override;
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*) override;
void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) override;
void onDrawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,

View File

@ -30,7 +30,7 @@ protected:
SkTDArray<SkCanvas*> fList;
void willSave() override;
SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) override;
SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
void willRestore() override;
void didConcat(const SkMatrix&) override;
@ -65,7 +65,6 @@ protected:
const SkPaint*, SrcRectConstraint) override;
void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst,
const SkPaint*) override;
void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*) override;
void onDrawVertices(VertexMode vmode, int vertexCount,
const SkPoint vertices[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,

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