Upstreaming changes from android.

- fix compile warnings in the GPU code
- upstream android specific code (ifdef protected)
- fail gracefully when a custom allocator fails



git-svn-id: http://skia.googlecode.com/svn/trunk@936 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
djsollen@google.com 2011-03-14 20:30:14 +00:00
parent 260db92d49
commit cd9d69b9ce
19 changed files with 249 additions and 18 deletions

View File

@ -64,7 +64,7 @@ public:
return fList[i].fRect;
}
const GrSetOp getOp(int i) const { return fList[i].fOp; }
GrSetOp getOp(int i) const { return fList[i].fOp; }
bool isRect() const {
if (1 == fList.count() && kRect_ClipType == fList[0].fType) {

View File

@ -245,7 +245,7 @@ public:
* @param stage the stage of sampler set
* @param matrix the matrix to set
*/
const void setSamplerMatrix(int stage, const GrMatrix& matrix) {
void setSamplerMatrix(int stage, const GrMatrix& matrix) {
fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
}

View File

@ -27,6 +27,8 @@ struct GrPoint;
*/
class GrPathRenderer {
public:
virtual ~GrPathRenderer() { };
/**
* Draws a path into the draw target. The target will already have its draw
* state configured for the draw.

View File

@ -468,16 +468,29 @@ public:
*/
int extractMipLevel(SkBitmap* dst, SkFixed sx, SkFixed sy);
void extractAlpha(SkBitmap* dst) const {
this->extractAlpha(dst, NULL, NULL, NULL);
bool extractAlpha(SkBitmap* dst) const {
return this->extractAlpha(dst, NULL, NULL, NULL);
}
void extractAlpha(SkBitmap* dst, const SkPaint* paint,
bool extractAlpha(SkBitmap* dst, const SkPaint* paint,
SkIPoint* offset) const {
this->extractAlpha(dst, paint, NULL, offset);
return this->extractAlpha(dst, paint, NULL, offset);
}
void extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
/** Set dst to contain alpha layer of this bitmap. If destination bitmap
fails to be initialized, e.g. because allocator can't allocate pixels
for it, dst will not be modified and false will be returned.
@param dst The bitmap to be filled with alpha layer
@param paint The paint to draw with
@param allocator Allocator used to allocate the pixelref for the dst
bitmap. If this is null, the standard HeapAllocator
will be used.
@param offset If not null, it is set to top-left coordinate to position
the returned bitmap so that it visually lines up with the
original
*/
bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
SkIPoint* offset) const;
void flatten(SkFlattenableWriteBuffer&) const;

View File

@ -626,6 +626,21 @@ public:
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
#ifdef ANDROID
/** Draw the text on path, with each character/glyph origin specified by the pos[]
array. The origin is interpreted by the Align setting in the paint.
@param text The text to be drawn
@param byteLength The number of bytes to read from the text parameter
@param pos Array of positions, used to position each character
@param paint The paint used for the text (e.g. color, size, style)
@param path The path to draw on
@param matrix The canvas matrix
*/
void drawPosTextOnPath(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix);
#endif
/** Draw the picture into this canvas. This method effective brackets the
playback of the picture's draw calls with save/restore, so the state
of this canvas will be unchanged after this call. This contrasts with

View File

@ -197,6 +197,11 @@ public:
virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
const SkPath& path, const SkMatrix* matrix,
const SkPaint& paint);
#ifdef ANDROID
virtual void drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix);
#endif
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,

View File

@ -55,6 +55,11 @@ public:
int scalarsPerPosition, const SkPaint& paint) const;
void drawTextOnPath(const char text[], size_t byteLength,
const SkPath&, const SkMatrix*, const SkPaint&) const;
#ifdef ANDROID
void drawPosTextOnPath(const char text[], size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) const;
#endif
void drawVertices(SkCanvas::VertexMode mode, int count,
const SkPoint vertices[], const SkPoint textures[],
const SkColor colors[], SkXfermode* xmode,

View File

@ -278,6 +278,18 @@ public:
static void SetSubpixelOrder(LCDOrder order);
static LCDOrder GetSubpixelOrder();
#ifdef ANDROID
///////////////////////////////////////////////////////////////////////////
/**
* Return the number of font units per em.
*
* @param fontID the font to query.
* @return the number of font units per em or 0 on error.
*/
static uint32_t GetUnitsPerEm(SkFontID fontID);
#endif
};
#endif

View File

@ -249,6 +249,12 @@ public:
*/
bool op(const SkRegion& rgna, const SkRegion& rgnb, Op op);
#ifdef ANDROID
/** Returns a new char* containing the list of rectangles in this region
*/
char* toString();
#endif
/** Returns the sequence of rectangles, sorted in Y and X, that make up
this region.
*/

View File

@ -52,6 +52,9 @@ public:
kMultiply_Mode, //!< [Sa * Da, Sc * Dc]
kScreen_Mode, //!< [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]
kAdd_Mode, //!< Saturate(S + D)
#ifdef ANDROID
kOverlay_Mode,
#endif
kModeCount
};

View File

@ -157,6 +157,10 @@ public:
void rotateY(SkScalar deg);
void rotateZ(SkScalar deg);
#ifdef ANDROID
void setCameraLocation(SkScalar x, SkScalar y, SkScalar z);
#endif
void getMatrix(SkMatrix*) const;
void applyToCanvas(SkCanvas*) const;

View File

@ -1237,10 +1237,11 @@ static bool GetBitmapAlpha(const SkBitmap& src, uint8_t SK_RESTRICT alpha[],
#include "SkMaskFilter.h"
#include "SkMatrix.h"
void SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
bool SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
Allocator *allocator, SkIPoint* offset) const {
SkDEBUGCODE(this->validate();)
SkBitmap tmpBitmap;
SkMatrix identity;
SkMask srcM, dstM;
@ -1260,14 +1261,20 @@ void SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
dstM.fRowBytes = SkAlign4(dstM.fBounds.width());
} else {
NO_FILTER_CASE:
dst->setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
tmpBitmap.setConfig(SkBitmap::kA8_Config, this->width(), this->height(),
srcM.fRowBytes);
dst->allocPixels(allocator, NULL);
GetBitmapAlpha(*this, dst->getAddr8(0, 0), srcM.fRowBytes);
if (!tmpBitmap.allocPixels(allocator, NULL)) {
// Allocation of pixels for alpha bitmap failed.
SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
tmpBitmap.width(), tmpBitmap.height());
return false;
}
GetBitmapAlpha(*this, tmpBitmap.getAddr8(0, 0), srcM.fRowBytes);
if (offset) {
offset->set(0, 0);
}
return;
tmpBitmap.swap(*dst);
return true;
}
SkAutoMaskImage srcCleanup(&srcM, true);
@ -1279,14 +1286,22 @@ void SkBitmap::extractAlpha(SkBitmap* dst, const SkPaint* paint,
SkAutoMaskImage dstCleanup(&dstM, false);
dst->setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
tmpBitmap.setConfig(SkBitmap::kA8_Config, dstM.fBounds.width(),
dstM.fBounds.height(), dstM.fRowBytes);
dst->allocPixels(allocator, NULL);
memcpy(dst->getPixels(), dstM.fImage, dstM.computeImageSize());
if (!tmpBitmap.allocPixels(allocator, NULL)) {
// Allocation of pixels for alpha bitmap failed.
SkDebugf("extractAlpha failed to allocate (%d,%d) alpha bitmap\n",
tmpBitmap.width(), tmpBitmap.height());
return false;
}
memcpy(tmpBitmap.getPixels(), dstM.fImage, dstM.computeImageSize());
if (offset) {
offset->set(dstM.fBounds.fLeft, dstM.fBounds.fTop);
}
SkDEBUGCODE(dst->validate();)
SkDEBUGCODE(tmpBitmap.validate();)
tmpBitmap.swap(*dst);
return true;
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -1401,6 +1401,22 @@ void SkCanvas::drawTextOnPath(const void* text, size_t byteLength,
ITER_END
}
#ifdef ANDROID
void SkCanvas::drawPosTextOnPath(const void* text, size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) {
ITER_BEGIN(paint, SkDrawFilter::kText_Type)
while (iter.next()) {
iter.fDevice->drawPosTextOnPath(iter, text, byteLength, pos,
paint, path, matrix);
}
ITER_END
}
#endif
void SkCanvas::drawVertices(VertexMode vmode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,

View File

@ -153,6 +153,14 @@ void SkDevice::drawTextOnPath(const SkDraw& draw, const void* text,
draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
}
#ifdef ANDROID
void SkDevice::drawPosTextOnPath(const SkDraw& draw, const void* text, size_t len,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) {
draw.drawPosTextOnPath((const char*)text, len, pos, paint, path, matrix);
}
#endif
void SkDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
int vertexCount,
const SkPoint verts[], const SkPoint textures[],

View File

@ -1940,6 +1940,70 @@ void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
}
}
#ifdef ANDROID
void SkDraw::drawPosTextOnPath(const char text[], size_t byteLength,
const SkPoint pos[], const SkPaint& paint,
const SkPath& path, const SkMatrix* matrix) const {
// nothing to draw
if (text == NULL || byteLength == 0 || fClip->isEmpty() ||
(paint.getAlpha() == 0 && paint.getXfermode() == NULL)) {
return;
}
SkMatrix scaledMatrix;
SkPathMeasure meas(path, false);
SkMeasureCacheProc glyphCacheProc = paint.getMeasureCacheProc(
SkPaint::kForward_TextBufferDirection, true);
// Copied (modified) from SkTextToPathIter constructor to setup paint
SkPaint tempPaint(paint);
tempPaint.setLinearText(true);
tempPaint.setMaskFilter(NULL); // don't want this affecting our path-cache lookup
if (tempPaint.getPathEffect() == NULL && !(tempPaint.getStrokeWidth() > 0
&& tempPaint.getStyle() != SkPaint::kFill_Style)) {
tempPaint.setStyle(SkPaint::kFill_Style);
tempPaint.setPathEffect(NULL);
}
// End copied from SkTextToPathIter constructor
// detach cache
SkGlyphCache* cache = tempPaint.detachCache(NULL);
// Must set scale, even if 1
SkScalar scale = SK_Scalar1;
scaledMatrix.setScale(scale, scale);
// Loop over all glyph ids
for (const char* stop = text + byteLength; text < stop; pos++) {
const SkGlyph& glyph = glyphCacheProc(cache, &text);
SkPath tmp;
const SkPath* glyphPath = cache->findPath(glyph);
if (glyphPath == NULL) {
continue;
}
SkMatrix m(scaledMatrix);
m.postTranslate(pos->fX, 0);
if (matrix) {
m.postConcat(*matrix);
}
morphpath(&tmp, *glyphPath, meas, m);
this->drawPath(tmp, tempPaint);
}
// re-attach cache
SkGlyphCache::AttachCache(cache);
}
#endif
///////////////////////////////////////////////////////////////////////////////
struct VertState {

View File

@ -19,6 +19,10 @@
#include "SkTemplates.h"
#include "SkThread.h"
#ifdef ANDROID
#include <stdio.h>
#endif
SkDEBUGCODE(int32_t gRgnAllocCounter;)
/////////////////////////////////////////////////////////////////////////////////////////////////
@ -190,6 +194,35 @@ bool SkRegion::op(const SkRegion& rgn, const SkIRect& rect, Op op)
//////////////////////////////////////////////////////////////////////////////////////
#ifdef ANDROID
char* SkRegion::toString()
{
Iterator iter(*this);
int count = 0;
while (!iter.done()) {
count++;
iter.next();
}
// 4 ints, up to 10 digits each plus sign, 3 commas, '(', ')', SkRegion() and '\0'
const int max = (count*((11*4)+5))+11+1;
char* result = (char*)malloc(max);
if (result == NULL) {
return NULL;
}
count = sprintf(result, "SkRegion(");
iter.reset(*this);
while (!iter.done()) {
const SkIRect& r = iter.rect();
count += sprintf(result+count, "(%d,%d,%d,%d)", r.fLeft, r.fTop, r.fRight, r.fBottom);
iter.next();
}
count += sprintf(result+count, ")");
return result;
}
#endif
//////////////////////////////////////////////////////////////////////////////////////
int SkRegion::count_runtype_values(int* itop, int* ibot) const
{
if (this == NULL)

View File

@ -29,7 +29,10 @@ static const struct Pair {
MAKE_PAIR(Lighten),
MAKE_PAIR(Multiply),
MAKE_PAIR(Screen),
{ SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode }
{ SkPorterDuff::kAdd_Mode, SkXfermode::kPlus_Mode },
#ifdef ANDROID
MAKE_PAIR(Overlay),
#endif
};
static bool find_pdmode(SkXfermode::Mode src, SkPorterDuff::Mode* dst) {

View File

@ -345,7 +345,7 @@ static bool getWidthAdvance(FT_Face face, int gId, int16_t* data) {
// static
SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
uint32_t fontID, bool perGlyphInfo) {
#if defined(SK_BUILD_FOR_MAC)
#if defined(SK_BUILD_FOR_MAC) || defined(ANDROID)
return NULL;
#else
SkAutoMutexAcquire ac(gFTMutex);
@ -540,6 +540,21 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
rec->setHinting(h);
}
#ifdef ANDROID
uint32_t SkFontHost::GetUnitsPerEm(SkFontID fontID) {
SkAutoMutexAcquire ac(gFTMutex);
SkFaceRec *rec = ref_ft_face(fontID);
uint16_t unitsPerEm = 0;
if (rec != NULL && rec->fFace != NULL) {
unitsPerEm = rec->fFace->units_per_EM;
unref_ft_face(rec->fFace);
}
return (uint32_t)unitsPerEm;
}
#endif
SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc)
: SkScalerContext(desc) {
SkAutoMutexAcquire ac(gFTMutex);

View File

@ -400,6 +400,18 @@ void Sk3DView::restore()
fRec = next;
}
#ifdef ANDROID
void Sk3DView::setCameraLocation(SkScalar x, SkScalar y, SkScalar z)
{
// the camera location is passed in inches, set in pt
SkScalar lz = z * SkFloatToScalar(72.0f);
fCamera.fLocation.set(x * SkFloatToScalar(72.0f), y * SkFloatToScalar(72.0f), lz);
fCamera.fObserver.set(0, 0, lz);
fCamera.update();
}
#endif
void Sk3DView::translate(SkScalar x, SkScalar y, SkScalar z)
{
fRec->fMatrix.preTranslate(x, y, z);