aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/core/SkColorPriv.h15
-rw-r--r--include/core/SkTDArray.h11
-rw-r--r--src/core/SkBitmapProcShader.cpp41
-rw-r--r--src/core/SkScan_Path.cpp6
4 files changed, 70 insertions, 3 deletions
diff --git a/include/core/SkColorPriv.h b/include/core/SkColorPriv.h
index 7658d5b..5129ac6 100644
--- a/include/core/SkColorPriv.h
+++ b/include/core/SkColorPriv.h
@@ -393,6 +393,21 @@ inline SkPMColor SkPixel16ToPixel32(U16CPU src)
return SkPackARGB32(0xFF, r, g, b);
}
+// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor
+static inline SkColor SkPixel16ToColor(U16CPU src) {
+ SkASSERT(src == SkToU16(src));
+
+ unsigned r = SkPacked16ToR32(src);
+ unsigned g = SkPacked16ToG32(src);
+ unsigned b = SkPacked16ToB32(src);
+
+ SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
+ SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
+ SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
+
+ return SkColorSetRGB(r, g, b);
+}
+
///////////////////////////////////////////////////////////////////////////////
typedef uint16_t SkPMColor16;
diff --git a/include/core/SkTDArray.h b/include/core/SkTDArray.h
index 5f6bbd8..954bcf8 100644
--- a/include/core/SkTDArray.h
+++ b/include/core/SkTDArray.h
@@ -86,6 +86,17 @@ public:
SkTSwap(fCount, other.fCount);
}
+ /** Return a ptr to the array of data, to be freed with sk_free. This also
+ resets the SkTDArray to be empty.
+ */
+ T* detach() {
+ T* array = fArray;
+ fArray = NULL;
+ fReserve = fCount = 0;
+ SkDEBUGCODE(fData = NULL;)
+ return array;
+ }
+
bool isEmpty() const { return fCount == 0; }
int count() const { return fCount; }
T* begin() const { return fArray; }
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 353388b..cb4d129 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -207,14 +207,51 @@ void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
///////////////////////////////////////////////////////////////////////////////
+#include "SkUnPreMultiply.h"
+#include "SkColorShader.h"
+
+// returns true and set color if the bitmap can be drawn as a single color
+// (for efficiency)
+static bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
+ if (1 != bm.width() || 1 != bm.height()) {
+ return false;
+ }
+
+ SkAutoLockPixels alp(bm);
+ if (!bm.readyToDraw()) {
+ return false;
+ }
+
+ switch (bm.config()) {
+ case SkBitmap::kARGB_8888_Config:
+ *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0));
+ return true;
+ case SkBitmap::kRGB_565_Config:
+ *color = SkPixel16ToColor(*bm.getAddr16(0, 0));
+ return true;
+ case SkBitmap::kIndex8_Config:
+ *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0));
+ return true;
+ default: // just skip the other configs for now
+ break;
+ }
+ return false;
+}
+
#include "SkTemplatesPriv.h"
SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
TileMode tmx, TileMode tmy,
void* storage, size_t storageSize) {
SkShader* shader;
- SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage,
- storageSize, (src, tmx, tmy));
+ SkColor color;
+ if (canUseColorShader(src, &color)) {
+ SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize,
+ (color));
+ } else {
+ SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage,
+ storageSize, (src, tmx, tmy));
+ }
return shader;
}
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp
index 211259f..636478d 100644
--- a/src/core/SkScan_Path.cpp
+++ b/src/core/SkScan_Path.cpp
@@ -383,7 +383,11 @@ extern "C" {
valuea = edgea->fX;
valueb = edgeb->fX;
}
- return valuea - valueb;
+
+ // this overflows if valuea >>> valueb or vice-versa
+ // return valuea - valueb;
+ // do perform the slower but safe compares
+ return (valuea < valueb) ? -1 : (valuea > valueb);
}
}