aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/SkDraw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/SkDraw.cpp')
-rw-r--r--src/core/SkDraw.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 19337f7..4460eb8 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -30,6 +30,15 @@
#include "SkBitmapProcShader.h"
#include "SkDrawProcs.h"
+#define LOG_TAG "SKIA"
+#include <cutils/log.h>
+
+#if defined(FIMG2D_ENABLED)
+#include "SkFimgApi4x.h"
+Fimg fimg;
+SkMutex gG2DMutex;
+#endif
+
//#define TRACE_BITMAP_DRAWS
#define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2)
@@ -1210,7 +1219,81 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
SkIRect ir;
ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height());
+#if defined(FIMG2D_ENABLED)
+ gG2DMutex.acquire();
+
+ SkAAClipBlitterWrapper wrapper(*fRC, blitter);
+ const SkRegion& clip = wrapper.getRgn();
+ SkRegion::Cliperator cliper(clip, ir);
+ const SkIRect& cr = cliper.rect();
+
+ memset(&fimg, 0, sizeof(fimg));
+
+ fimg.matrixType = (int)matrix.getType();
+ fimg.matrixSx = matrix.getScaleX();
+ fimg.matrixSy = matrix.getScaleY();
+
+ fimg.srcX = cr.fLeft - ix;
+ fimg.srcY = cr.fTop - iy;
+ fimg.srcW = cr.width();
+ fimg.srcH = cr.height();
+ fimg.srcFWStride = bitmap.rowBytes();
+ fimg.srcFH = bitmap.height();
+ fimg.srcBPP = bitmap.bytesPerPixel();
+ fimg.srcColorFormat = bitmap.getConfig();
+ fimg.srcAddr = (unsigned char *)bitmap.getAddr(0, 0);
+
+ fimg.dstX = cr.fLeft;
+ fimg.dstY = cr.fTop;
+ fimg.dstW = cr.width();
+ fimg.dstH = cr.height();
+ fimg.dstFWStride = fBitmap->rowBytes();
+ fimg.dstFH = fBitmap->height();
+ fimg.dstBPP = fBitmap->bytesPerPixel();
+ fimg.dstColorFormat = fBitmap->config();
+ fimg.dstAddr = (unsigned char *)fBitmap->getAddr(0,0);
+
+ if (((cr.fLeft - ix) < 0) || ((cr.fTop - iy) < 0) || (cr.fLeft < 0) || (cr.fTop < 0))
+ fimg.srcAddr = NULL;
+
+ fimg.clipT = cr.fTop;
+ fimg.clipB = cr.fBottom;
+ fimg.clipL = cr.fLeft;
+ fimg.clipR = cr.fRight;
+
+ fimg.mskAddr = NULL;
+ fimg.rotate = 0;
+
+ SkXfermode::Mode mode;
+ SkXfermode::IsMode(paint.getXfermode(), &mode);
+ fimg.xfermode = mode;
+
+ fimg.isDither = paint.isDither();
+ fimg.colorFilter = (int)paint.getColorFilter();
+
+ fimg.alpha = paint.getAlpha();
+ if (bitmap.isOpaque() && (255 == fimg.alpha))
+ fimg.alpha = 255;
+
+ if (fimg.srcAddr != NULL) {
+ int retFimg = FimgApiStretch(&fimg, __func__);
+
+ if (retFimg == FIMGAPI_FINISHED) {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ } else {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ SkScan::FillIRect(ir, *fRC, blitter);
+ }
+ } else {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ SkScan::FillIRect(ir, *fRC, blitter);
+ }
+#else
SkScan::FillIRect(ir, *fRC, blitter);
+#endif
return;
}
}
@@ -1230,7 +1313,46 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
r.set(0, 0, SkIntToScalar(bitmap.width()),
SkIntToScalar(bitmap.height()));
// is this ok if paint has a rasterizer?
+
+#if defined(FIMG2D_ENABLED)
+ gG2DMutex.acquire();
+
+ fimg.matrixType = (int)matrix.getType();
+ fimg.matrixSx = matrix.getScaleX();
+ fimg.matrixSy = matrix.getScaleY();
+
+ SkIRect fimg_ir;
+ r.round(&fimg_ir);
+ fimg.srcX = fimg_ir.fLeft;
+ fimg.srcY = fimg_ir.fTop;
+ fimg.srcW = fimg_ir.width();
+ fimg.srcH = fimg_ir.height();
+
+ fimg.srcFWStride = bitmap.rowBytes();
+ fimg.srcFH = bitmap.height();
+ fimg.srcBPP = bitmap.bytesPerPixel();
+ fimg.srcColorFormat = bitmap.getConfig();
+ fimg.srcAddr = (unsigned char *)bitmap.getAddr(0, 0);
+
+ if ((r.fLeft < 0) || (r.fTop < 0))
+ fimg.srcAddr = NULL;
+
+ fimg.dstFWStride = fBitmap->rowBytes();
+ fimg.dstFH = fBitmap->height();
+ fimg.dstBPP = fBitmap->bytesPerPixel();
+ fimg.dstColorFormat = fBitmap->config();
+ fimg.dstAddr = (unsigned char *)fBitmap->getAddr(0,0);
+
+ fimg.mskAddr = NULL;
+ fimg.rotate = 0;
+
+ fimg.alpha = paint.getAlpha();
+ if (bitmap.isOpaque() && (255 == fimg.alpha))
+ fimg.alpha = 255;
+ draw.drawRect_withG2D(r, install.paintWithShader());
+#else
draw.drawRect(r, install.paintWithShader());
+#endif
}
}
@@ -2653,3 +2775,142 @@ bool SkDraw::DrawToMask(const SkPath& devPath, const SkIRect* clipBounds,
return true;
}
+
+#if defined(FIMG2D_ENABLED)
+void SkDraw::drawRect_withG2D(const SkRect& rect, const SkPaint& paint) const {
+ SkDEBUGCODE(this->validate();)
+
+ // nothing to draw
+ if (fRC->isEmpty()) {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ return;
+ }
+
+ SkPoint strokeSize;
+ RectType rtype = ComputeRectType(paint, *fMatrix, &strokeSize);
+
+#ifdef SK_DISABLE_FAST_AA_STROKE_RECT
+ if (kStroke_RectType == rtype && paint.isAntiAlias())
+ rtype = kPath_RectType;
+#endif
+
+ if (kPath_RectType == rtype) {
+ SkPath tmp;
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ tmp.addRect(rect);
+ tmp.setFillType(SkPath::kWinding_FillType);
+ this->drawPath(tmp, paint, NULL, true);
+ return;
+ }
+
+ const SkMatrix& matrix = *fMatrix;
+ SkRect devRect;
+
+ // transform rect into devRect
+ matrix.mapXY(rect.fLeft, rect.fTop, rect_points(devRect, 0));
+ matrix.mapXY(rect.fRight, rect.fBottom, rect_points(devRect, 1));
+ devRect.sort();
+
+ if (fBounder && !fBounder->doRect(devRect, paint)) {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ return;
+ }
+
+ // look for the quick exit, before we build a blitter
+ {
+ SkIRect ir;
+ devRect.roundOut(&ir);
+ if (paint.getStyle() != SkPaint::kFill_Style) {
+ // extra space for hairlines
+ ir.inset(-1, -1);
+ }
+ if (fRC->quickReject(ir)) {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ return;
+ }
+ }
+
+ SkAutoBlitterChoose blitterStorage(*fBitmap, matrix, paint);
+ const SkRasterClip& clip = *fRC;
+ SkBlitter* blitter = blitterStorage.get();
+
+ if (devRect.fLeft < 0)
+ fimg.srcAddr = NULL;
+
+ if (fimg.srcAddr != NULL) {
+ SkIRect fimg_ir;
+ devRect.round(&fimg_ir);
+ fimg.dstX = fimg_ir.fLeft;
+ fimg.dstY = fimg_ir.fTop;
+ fimg.dstW = fimg_ir.width();
+ fimg.dstH = fimg_ir.height();
+
+ if (clip.isRect()) {
+ const SkIRect& clipBounds = clip.getBounds();
+ fimg.clipT = clipBounds.fTop;
+ fimg.clipB = clipBounds.fBottom;
+ fimg.clipL = clipBounds.fLeft;
+ fimg.clipR = clipBounds.fRight;
+ } else {
+ fimg.srcAddr = NULL;
+ fimg.clipT = 0;
+ fimg.clipB = 0;
+ fimg.clipL = 0;
+ fimg.clipR = 0;
+ }
+
+ SkXfermode::Mode mode;
+ SkXfermode::IsMode(paint.getXfermode(), &mode);
+ fimg.xfermode = mode;
+ fimg.isDither = paint.isDither();
+ fimg.isFilter = paint.isFilterBitmap();
+ fimg.colorFilter = (int)paint.getColorFilter();
+
+ if ((fimg.dstX<0)||(fimg.dstW<=0)||(fimg.dstH<=0))
+ fimg.srcAddr = NULL;
+
+ if (fimg.srcAddr != NULL) {
+ int retFimg;
+ retFimg = FimgApiStretch(&fimg, __func__);
+ if (retFimg) {
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ return;
+ }
+ }
+ }
+ fimg.srcAddr = NULL;
+ gG2DMutex.release();
+ /* we want to "fill" if we are kFill or kStrokeAndFill, since in the latter
+ * case we are also hairline (if we've gotten to here), which devolves to
+ * effectively just kFill
+ */
+
+ switch (rtype) {
+ case kFill_RectType:
+ if (paint.isAntiAlias())
+ SkScan::AntiFillRect(devRect, clip, blitter);
+ else
+ SkScan::FillRect(devRect, clip, blitter);
+ break;
+ case kStroke_RectType:
+ if (paint.isAntiAlias())
+ SkScan::AntiFrameRect(devRect, strokeSize, clip, blitter);
+ else
+ SkScan::FrameRect(devRect, strokeSize, clip, blitter);
+ break;
+ case kHair_RectType:
+ if (paint.isAntiAlias())
+ SkScan::AntiHairRect(devRect, clip, blitter);
+ else
+ SkScan::HairRect(devRect, clip, blitter);
+ break;
+ default:
+ SkDEBUGFAIL("bad rtype");
+ }
+}
+#endif