/*
* 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 SkGPipePriv_DEFINED
#define SkGPipePriv_DEFINED
#include "SkTypes.h"
#define UNIMPLEMENTED
// these must be contiguous, 0...N-1
enum PaintFlats {
kColorFilter_PaintFlat,
kDrawLooper_PaintFlat,
kImageFilter_PaintFlat,
kMaskFilter_PaintFlat,
kPathEffect_PaintFlat,
kRasterizer_PaintFlat,
kShader_PaintFlat,
kXfermode_PaintFlat,
kLast_PaintFlat = kXfermode_PaintFlat
};
#define kCount_PaintFlats (kLast_PaintFlat + 1)
enum DrawOps {
kSkip_DrawOp, // skip an addition N bytes (N == data)
// these match Canvas apis
kClipPath_DrawOp,
kClipRegion_DrawOp,
kClipRect_DrawOp,
kClipRRect_DrawOp,
kConcat_DrawOp,
kDrawBitmap_DrawOp,
kDrawBitmapNine_DrawOp,
kDrawBitmapRectToRect_DrawOp,
kDrawDRRect_DrawOp,
kDrawImage_DrawOp,
kDrawImageRect_DrawOp,
kDrawOval_DrawOp,
kDrawPaint_DrawOp,
kDrawPatch_DrawOp,
kDrawPath_DrawOp,
kDrawPicture_DrawOp,
kDrawPoints_DrawOp,
kDrawPosText_DrawOp,
kDrawPosTextH_DrawOp,
kDrawRect_DrawOp,
kDrawRRect_DrawOp,
kDrawSprite_DrawOp,
kDrawText_DrawOp,
kDrawTextBlob_DrawOp,
kDrawTextOnPath_DrawOp,
kDrawVertices_DrawOp,
kRestore_DrawOp,
kRotate_DrawOp,
kSave_DrawOp,
kSaveLayer_DrawOp,
kScale_DrawOp,
kSetMatrix_DrawOp,
kSkew_DrawOp,
kTranslate_DrawOp,
kPaintOp_DrawOp,
kSetTypeface_DrawOp,
kSetAnnotation_DrawOp,
kDef_Typeface_DrawOp,
kDef_Flattenable_DrawOp,
kDef_Bitmap_DrawOp,
kDef_Factory_DrawOp,
// these are signals to playback, not drawing verbs
kReportFlags_DrawOp,
kShareBitmapHeap_DrawOp,
kShareImageHeap_DrawOp,
kDone_DrawOp,
};
/**
* DrawOp packs into a 32bit int as follows
*
* DrawOp:8 - Flags:4 - Data:20
*
* Flags and Data are called out separately, so we can reuse Data between
* different Ops that might have different Flags. e.g. Data might be a Paint
* index for both drawRect (no flags) and saveLayer (does have flags).
*
* All Ops that take a SkPaint use their Data field to store the index to
* the paint (previously defined with kPaintOp_DrawOp).
*/
#define DRAWOPS_OP_BITS 8
#define DRAWOPS_FLAG_BITS 4
#define DRAWOPS_DATA_BITS 20
#define DRAWOPS_OP_MASK ((1 << DRAWOPS_OP_BITS) - 1)
#define DRAWOPS_FLAG_MASK ((1 << DRAWOPS_FLAG_BITS) - 1)
#define DRAWOPS_DATA_MASK ((1 << DRAWOPS_DATA_BITS) - 1)
static inline unsigned DrawOp_unpackOp(uint32_t op32) {
return (op32 >> (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS));
}
static inline unsigned DrawOp_unpackFlags(uint32_t op32) {
return (op32 >> DRAWOPS_DATA_BITS) & DRAWOPS_FLAG_MASK;
}
static inline unsigned DrawOp_unpackData(uint32_t op32) {
return op32 & DRAWOPS_DATA_MASK;
}
static inline uint32_t DrawOp_packOpFlagData(DrawOps op, unsigned flags, unsigned data) {
SkASSERT(0 == (op & ~DRAWOPS_OP_MASK));
SkASSERT(0 == (flags & ~DRAWOPS_FLAG_MASK));
SkASSERT(0 == (data & ~DRAWOPS_DATA_MASK));
return (op << (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS)) |
(flags << DRAWOPS_DATA_BITS) |
data;
}
/** DrawOp specific flag bits
*/
enum {
kSaveLayer_HasBounds_DrawOpFlag = 1 << 0,
kSaveLayer_HasPaint_DrawOpFlag = 1 << 1,
};
enum {
kDrawTextOnPath_HasMatrix_DrawOpFlag = 1 << 0
};
enum {
kDrawVertices_HasTexs_DrawOpFlag = 1 << 0,
kDrawVertices_HasColors_DrawOpFlag = 1 << 1,
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
kDrawVertices_HasXfermode_DrawOpFlag = 1 << 3,
};
// These are shared between drawbitmap and drawimage
enum {
kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0,
// Specific to drawBitmapRect, but needs to be different from HasPaint,
// which is used for all drawBitmap calls, so include it here.
kDrawBitmap_HasSrcRect_DrawOpFlag = 1 << 1,
// SkCanvas::DrawBitmapRectFlags::kBleed_DrawBitmapRectFlag is
// converted into and out of this flag to save space
kDrawBitmap_Bleed_DrawOpFlag = 1 << 2,
};
enum {
kClip_HasAntiAlias_DrawOpFlag = 1 << 0,
};
///////////////////////////////////////////////////////////////////////////////
class BitmapInfo : SkNoncopyable {
public:
BitmapInfo(SkBitmap* bitmap, uint32_t genID, int toBeDrawnCount)
: fBitmap(bitmap)
, fGenID(genID)
, fBytesAllocated(0)
, fMoreRecentlyUsed(NULL)
, fLessRecentlyUsed(NULL)
, fToBeDrawnCount(toBeDrawnCount)
{}
~BitmapInfo() {
SkASSERT(0 == fToBeDrawnCount);
SkDELETE(fBitmap);
}
void addDraws(int drawsToAdd) {
if (0 == fToBeDrawnCount) {
// The readers will only ever decrement the count, so once the
// count is zero, the writer will be the only one modifying it,
// so it does not need to be an atomic operation.
fToBeDrawnCount = drawsToAdd;
} else {
sk_atomic_add(&fToBeDrawnCount, drawsToAdd);
}
}
void decDraws() {
sk_atomic_dec(&fToBeDrawnCount);
}
int drawCount() const {
return fToBeDrawnCount;
}
SkBitmap* fBitmap;
// Store the generation ID of the original bitmap, since copying does
// not copy this field, so fBitmap's generation ID will not be useful
// for comparing.
// FIXME: Is it reasonable to make copying a bitmap/pixelref copy the
// generation ID?
uint32_t fGenID;
// Keep track of the bytes allocated for this bitmap. When replacing the
// bitmap or removing this BitmapInfo we know how much memory has been
// reclaimed.
size_t fBytesAllocated;
// TODO: Generalize the LRU caching mechanism
BitmapInfo* fMoreRecentlyUsed;
BitmapInfo* fLessRecentlyUsed;
private:
int fToBeDrawnCount;
};
static inline bool shouldFlattenBitmaps(uint32_t flags) {
return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag
&& !(flags & SkGPipeWriter::kSharedAddressSpace_Flag));
}
class SkImageHeap : public SkRefCnt {
public:
SkImageHeap();
virtual ~SkImageHeap();
// slot must be "valid" -- 0 is never valid
const SkImage* get(int32_t slot) const;
// returns 0 if not found, else returns slot
int32_t find(const SkImage*) const;
// returns non-zero value for where the image was stored
int32_t insert(const SkImage*);
private:
SkTDArray<const SkImage*> fArray;
};
///////////////////////////////////////////////////////////////////////////////
enum PaintOps {
kReset_PaintOp, // no arg
kFlags_PaintOp, // arg inline
kColor_PaintOp, // arg 32
kFilterLevel_PaintOp, // arg inline
kStyle_PaintOp, // arg inline
kJoin_PaintOp, // arg inline
kCap_PaintOp, // arg inline
kWidth_PaintOp, // arg scalar
kMiter_PaintOp, // arg scalar
kEncoding_PaintOp, // arg inline - text
kHinting_PaintOp, // arg inline - text
kAlign_PaintOp, // arg inline - text
kTextSize_PaintOp, // arg scalar - text
kTextScaleX_PaintOp,// arg scalar - text
kTextSkewX_PaintOp, // arg scalar - text
kTypeface_PaintOp, // arg inline (index) - text
kFlatIndex_PaintOp, // flags=paintflat, data=index
};
#define PAINTOPS_OP_BITS 8
#define PAINTOPS_FLAG_BITS 4
#define PAINTOPS_DATA_BITS 20
#define PAINTOPS_OP_MASK ((1 << PAINTOPS_OP_BITS) - 1)
#define PAINTOPS_FLAG_MASK ((1 << PAINTOPS_FLAG_BITS) - 1)
#define PAINTOPS_DATA_MASK ((1 << PAINTOPS_DATA_BITS) - 1)
static inline unsigned PaintOp_unpackOp(uint32_t op32) {
return (op32 >> (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS));
}
static inline unsigned PaintOp_unpackFlags(uint32_t op32) {
return (op32 >> PAINTOPS_DATA_BITS) & PAINTOPS_FLAG_MASK;
}
static inline unsigned PaintOp_unpackData(uint32_t op32) {
return op32 & PAINTOPS_DATA_MASK;
}
static inline uint32_t PaintOp_packOp(PaintOps op) {
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
return op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS);
}
static inline uint32_t PaintOp_packOpData(PaintOps op, unsigned data) {
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));
return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) | data;
}
static inline uint32_t PaintOp_packOpFlagData(PaintOps op, unsigned flags, unsigned data) {
SkASSERT(0 == (op & ~PAINTOPS_OP_MASK));
SkASSERT(0 == (flags & ~PAINTOPS_FLAG_MASK));
SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK));
return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) |
(flags << PAINTOPS_DATA_BITS) |
data;
}
#endif