Commit 3026a9ec authored by Mike Reed's avatar Mike Reed
Browse files

refresh from skia trunk

- correctly respect dither for index bitmaps
- fix copyTo to respect isOpaque()
- sanity check in antipath (need to investigate root cause)
- warning fix in bitmap sampler
parent 2ce88a32
......@@ -508,6 +508,9 @@ public:
*/
void setFlags(unsigned flags);
bool isOpaque() const { return (fFlags & kColorsAreOpaque_Flag) != 0; }
void setIsOpaque(bool isOpaque);
/** Returns the number of colors in the table.
*/
int count() const { return fCount; }
......
......@@ -162,7 +162,10 @@ static inline int SkNextLog2(uint32_t value) {
With this requirement, we can generate faster instructions on some
architectures.
*/
#if defined(__arm__) && !defined(__thumb__) && !defined(__ARM_ARCH_4__)
#if defined(__arm__) \
&& !defined(__thumb__) \
&& !defined(__ARM_ARCH_4__) \
&& !defined(__ARM_ARCH_5T__)
static inline int32_t SkMulS16(S16CPU x, S16CPU y) {
SkASSERT((int16_t)x == x);
SkASSERT((int16_t)y == y);
......@@ -170,7 +173,6 @@ static inline int SkNextLog2(uint32_t value) {
asm("smulbb %0, %1, %2 \n"
: "=r"(product)
: "r"(x), "r"(y)
:
);
return product;
}
......
......@@ -793,6 +793,8 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
canvas.drawBitmap(*this, 0, 0, &paint);
}
tmp.setIsOpaque(this->isOpaque());
dst->swap(tmp);
return true;
}
......@@ -1042,7 +1044,7 @@ SkFixed SkBitmap::ComputeMipLevel(SkFixed sx, SkFixed sy) {
///////////////////////////////////////////////////////////////////////////////
static void GetBitmapAlpha(const SkBitmap& src, uint8_t SK_RESTRICT alpha[],
static bool GetBitmapAlpha(const SkBitmap& src, uint8_t SK_RESTRICT alpha[],
int alphaRowBytes) {
SkASSERT(alpha != NULL);
SkASSERT(alphaRowBytes >= src.width());
......@@ -1052,6 +1054,16 @@ static void GetBitmapAlpha(const SkBitmap& src, uint8_t SK_RESTRICT alpha[],
int h = src.height();
int rb = src.rowBytes();
SkAutoLockPixels alp(src);
if (!src.readyToDraw()) {
// zero out the alpha buffer and return
while (--h >= 0) {
memset(alpha, 0, w);
alpha += alphaRowBytes;
}
return false;
}
if (SkBitmap::kA8_Config == config && !src.isOpaque()) {
const uint8_t* s = src.getAddr8(0, 0);
while (--h >= 0) {
......@@ -1094,6 +1106,7 @@ static void GetBitmapAlpha(const SkBitmap& src, uint8_t SK_RESTRICT alpha[],
} else { // src is opaque, so just fill alpha[] with 0xFF
memset(alpha, 0xFF, h * alphaRowBytes);
}
return true;
}
#include "SkPaint.h"
......
......@@ -102,19 +102,19 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
}
// update fFlags
fFlags = 0;
uint32_t flags = 0;
if (bitmapIsOpaque && (255 == this->getPaintAlpha())) {
fFlags |= kOpaqueAlpha_Flag;
flags |= kOpaqueAlpha_Flag;
}
switch (fState.fBitmap->config()) {
case SkBitmap::kRGB_565_Config:
fFlags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
break;
case SkBitmap::kIndex8_Config:
case SkBitmap::kARGB_8888_Config:
if (bitmapIsOpaque) {
fFlags |= kHasSpan16_Flag;
flags |= kHasSpan16_Flag;
}
break;
case SkBitmap::kA8_Config:
......@@ -123,11 +123,19 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
break;
}
if (paint.isDither()) {
// gradients can auto-dither in their 16bit sampler, but we don't so
// we clear the flag here
flags &= ~kHasSpan16_Flag;
}
// if we're only 1-pixel heigh, and we don't rotate, then we can claim this
if (1 == fState.fBitmap->height() &&
only_scale_and_translate(this->getTotalInverse())) {
fFlags |= kConstInY_Flag;
flags |= kConstInY_Flag;
}
fFlags = flags;
return true;
}
......
......@@ -896,16 +896,8 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
((SkPaint*)&paint)->setShader(shader)->unref();
}
bool doDither = paint.isDither();
if (shader)
{
if (!shader->setContext(device, paint, matrix))
return SkNEW(SkNullBlitter);
// disable dither if our shader is natively 16bit (no need to upsample)
if (shader->getFlags() & SkShader::kIntrinsicly16_Flag)
doDither = false;
if (shader && !shader->setContext(device, paint, matrix)) {
return SkNEW(SkNullBlitter);
}
switch (device.getConfig()) {
......@@ -929,7 +921,7 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device,
{
if (mode)
SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, storage, storageSize, (device, paint));
else if (SkShader::CanCallShadeSpan16(shader->getFlags()) && !doDither)
else if (shader->canCallShadeSpan16())
SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage, storageSize, (device, paint));
else
SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage, storageSize, (device, paint));
......
......@@ -132,6 +132,14 @@ const uint16_t* SkColorTable::lock16BitCache()
return f16BitCache;
}
void SkColorTable::setIsOpaque(bool isOpaque) {
if (isOpaque) {
fFlags |= kColorsAreOpaque_Flag;
} else {
fFlags &= ~kColorsAreOpaque_Flag;
}
}
///////////////////////////////////////////////////////////////////////////////
SkColorTable::SkColorTable(SkFlattenableReadBuffer& buffer) {
......
......@@ -286,6 +286,13 @@ void MaskSuperBlitter::blitH(int x, int y, int width)
SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
iy -= fMask.fBounds.fTop; // make it relative to 0
// This should never happen, but it does. Until the true cause is
// discovered, let's skip this span instead of crashing.
// See http://crbug.com/17569.
if (iy < 0) {
return;
}
#ifdef SK_DEBUG
{
int ix = x >> SHIFT;
......@@ -359,6 +366,7 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
if (ir.isEmpty()) {
return;
}
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
// use bit-or since we expect all to pass, so no need to go slower with
// a short-circuiting logical-or
......@@ -397,11 +405,14 @@ void SkScan::AntiFillPath(const SkPath& path, const SkRegion& clip,
superClipRect = &superRect;
}
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
// MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
// if we're an inverse filltype
if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir))
{
MaskSuperBlitter superBlit(blitter, ir, clip);
SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
sk_fill_path(path, superClipRect, &superBlit, ir.fBottom, SHIFT, clip);
}
else
......
......@@ -356,6 +356,10 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source,
}
break;
case SkBitmap::kIndex8_Config:
if (paint.isDither()) {
// we don't support dither yet in these special cases
break;
}
if (source.isOpaque()) {
if (255 == alpha) {
SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque,
......
......@@ -192,7 +192,7 @@ static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow,
// Index
#define A32_MASK_IN_PLACE (SK_A32_MASK << SK_A32_SHIFT)
#define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT)
static bool Sample_Index_D8888(void* SK_RESTRICT dstRow,
const uint8_t* SK_RESTRICT src,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment