summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/src/core/SkBitmapProcShader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/src/core/SkBitmapProcShader.cpp')
-rw-r--r--chromium/third_party/skia/src/core/SkBitmapProcShader.cpp256
1 files changed, 153 insertions, 103 deletions
diff --git a/chromium/third_party/skia/src/core/SkBitmapProcShader.cpp b/chromium/third_party/skia/src/core/SkBitmapProcShader.cpp
index bb161192763..8e03a804271 100644
--- a/chromium/third_party/skia/src/core/SkBitmapProcShader.cpp
+++ b/chromium/third_party/skia/src/core/SkBitmapProcShader.cpp
@@ -6,7 +6,8 @@
* found in the LICENSE file.
*/
#include "SkColorPriv.h"
-#include "SkFlattenableBuffers.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
#include "SkPixelRef.h"
#include "SkErrorInternals.h"
#include "SkBitmapProcShader.h"
@@ -17,11 +18,11 @@
#endif
bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) {
- switch (bm.config()) {
- case SkBitmap::kA8_Config:
- case SkBitmap::kRGB_565_Config:
- case SkBitmap::kIndex8_Config:
- case SkBitmap::kARGB_8888_Config:
+ switch (bm.colorType()) {
+ case kAlpha_8_SkColorType:
+ case kRGB_565_SkColorType:
+ case kIndex_8_SkColorType:
+ case kN32_SkColorType:
// if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx))
return true;
default:
@@ -30,21 +31,20 @@ bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) {
return false;
}
-SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src,
- TileMode tmx, TileMode tmy) {
+SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
+ const SkMatrix* localMatrix)
+ : INHERITED(localMatrix) {
fRawBitmap = src;
- fState.fTileModeX = (uint8_t)tmx;
- fState.fTileModeY = (uint8_t)tmy;
- fFlags = 0; // computed in setContext
+ fTileModeX = (uint8_t)tmx;
+ fTileModeY = (uint8_t)tmy;
}
-SkBitmapProcShader::SkBitmapProcShader(SkFlattenableReadBuffer& buffer)
+SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer)
: INHERITED(buffer) {
buffer.readBitmap(&fRawBitmap);
fRawBitmap.setImmutable();
- fState.fTileModeX = buffer.readUInt();
- fState.fTileModeY = buffer.readUInt();
- fFlags = 0; // computed in setContext
+ fTileModeX = buffer.readUInt();
+ fTileModeY = buffer.readUInt();
}
SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
@@ -57,18 +57,18 @@ SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture,
texM->reset();
}
if (xy) {
- xy[0] = (TileMode)fState.fTileModeX;
- xy[1] = (TileMode)fState.fTileModeY;
+ xy[0] = (TileMode)fTileModeX;
+ xy[1] = (TileMode)fTileModeY;
}
return kDefault_BitmapType;
}
-void SkBitmapProcShader::flatten(SkFlattenableWriteBuffer& buffer) const {
+void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.writeBitmap(fRawBitmap);
- buffer.writeUInt(fState.fTileModeX);
- buffer.writeUInt(fState.fTileModeY);
+ buffer.writeUInt(fTileModeX);
+ buffer.writeUInt(fTileModeY);
}
static bool only_scale_and_translate(const SkMatrix& matrix) {
@@ -87,7 +87,7 @@ static bool valid_for_drawing(const SkBitmap& bm) {
if (NULL == bm.pixelRef()) {
return false; // no pixels to read
}
- if (SkBitmap::kIndex8_Config == bm.config()) {
+ if (kIndex_8_SkColorType == bm.colorType()) {
// ugh, I have to lock-pixels to inspect the colortable
SkAutoLockPixels alp(bm);
if (!bm.getColorTable()) {
@@ -97,25 +97,44 @@ static bool valid_for_drawing(const SkBitmap& bm) {
return true;
}
-bool SkBitmapProcShader::setContext(const SkBitmap& device,
- const SkPaint& paint,
- const SkMatrix& matrix) {
+SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const {
if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) {
- return false;
+ return NULL;
}
- // do this first, so we have a correct inverse matrix
- if (!this->INHERITED::setContext(device, paint, matrix)) {
- return false;
+ SkMatrix totalInverse;
+ // Do this first, so we know the matrix can be inverted.
+ if (!this->computeTotalInverse(rec, &totalInverse)) {
+ return NULL;
}
- fState.fOrigBitmap = fRawBitmap;
- if (!fState.chooseProcs(this->getTotalInverse(), paint)) {
- this->INHERITED::endContext();
- return false;
+ void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
+ SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState);
+
+ SkASSERT(state);
+ state->fTileModeX = fTileModeX;
+ state->fTileModeY = fTileModeY;
+ state->fOrigBitmap = fRawBitmap;
+ if (!state->chooseProcs(totalInverse, *rec.fPaint)) {
+ state->~SkBitmapProcState();
+ return NULL;
}
- const SkBitmap& bitmap = *fState.fBitmap;
+ return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state));
+}
+
+size_t SkBitmapProcShader::contextSize() const {
+ // The SkBitmapProcState is stored outside of the context object, with the context holding
+ // a pointer to it.
+ return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState);
+}
+
+SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(
+ const SkBitmapProcShader& shader, const ContextRec& rec, SkBitmapProcState* state)
+ : INHERITED(shader, rec)
+ , fState(state)
+{
+ const SkBitmap& bitmap = *fState->fBitmap;
bool bitmapIsOpaque = bitmap.isOpaque();
// update fFlags
@@ -124,23 +143,23 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
flags |= kOpaqueAlpha_Flag;
}
- switch (bitmap.config()) {
- case SkBitmap::kRGB_565_Config:
+ switch (bitmap.colorType()) {
+ case kRGB_565_SkColorType:
flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag);
break;
- case SkBitmap::kIndex8_Config:
- case SkBitmap::kARGB_8888_Config:
+ case kIndex_8_SkColorType:
+ case kN32_SkColorType:
if (bitmapIsOpaque) {
flags |= kHasSpan16_Flag;
}
break;
- case SkBitmap::kA8_Config:
+ case kAlpha_8_SkColorType:
break; // never set kHasSpan16_Flag
default:
break;
}
- if (paint.isDither() && bitmap.config() != SkBitmap::kRGB_565_Config) {
+ if (rec.fPaint->isDither() && bitmap.colorType() != kRGB_565_SkColorType) {
// gradients can auto-dither in their 16bit sampler, but we don't so
// we clear the flag here.
flags &= ~kHasSpan16_Flag;
@@ -156,12 +175,12 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device,
}
fFlags = flags;
- return true;
}
-void SkBitmapProcShader::endContext() {
- fState.endContext();
- this->INHERITED::endContext();
+SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() {
+ // The bitmap proc state has been created outside of the context on memory that will be freed
+ // elsewhere. Only call the destructor but leave the freeing of the memory to the caller.
+ fState->~SkBitmapProcState();
}
#define BUF_MAX 128
@@ -175,8 +194,9 @@ void SkBitmapProcShader::endContext() {
#define TEST_BUFFER_EXTRA 0
#endif
-void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
- const SkBitmapProcState& state = fState;
+void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[],
+ int count) {
+ const SkBitmapProcState& state = *fState;
if (state.getShaderProc32()) {
state.getShaderProc32()(state, x, y, dstC, count);
return;
@@ -185,7 +205,7 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA];
SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32();
- int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
+ int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX);
SkASSERT(state.fBitmap->getPixels());
SkASSERT(state.fBitmap->pixelRef() == NULL ||
@@ -219,16 +239,17 @@ void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
}
}
-SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) {
- if (fState.getShaderProc32()) {
- *ctx = &fState;
- return (ShadeProc)fState.getShaderProc32();
+SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asAShadeProc(void** ctx) {
+ if (fState->getShaderProc32()) {
+ *ctx = fState;
+ return (ShadeProc)fState->getShaderProc32();
}
return NULL;
}
-void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
- const SkBitmapProcState& state = fState;
+void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint16_t dstC[],
+ int count) {
+ const SkBitmapProcState& state = *fState;
if (state.getShaderProc16()) {
state.getShaderProc16()(state, x, y, dstC, count);
return;
@@ -237,7 +258,7 @@ void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
uint32_t buffer[BUF_MAX];
SkBitmapProcState::MatrixProc mproc = state.getMatrixProc();
SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16();
- int max = fState.maxCountForBufferSize(sizeof(buffer));
+ int max = state.maxCountForBufferSize(sizeof(buffer));
SkASSERT(state.fBitmap->getPixels());
SkASSERT(state.fBitmap->pixelRef() == NULL ||
@@ -277,14 +298,14 @@ static bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
return false;
}
- switch (bm.config()) {
- case SkBitmap::kARGB_8888_Config:
+ switch (bm.colorType()) {
+ case kN32_SkColorType:
*color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0));
return true;
- case SkBitmap::kRGB_565_Config:
+ case kRGB_565_SkColorType:
*color = SkPixel16ToColor(*bm.getAddr16(0, 0));
return true;
- case SkBitmap::kIndex8_Config:
+ case kIndex_8_SkColorType:
*color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0));
return true;
default: // just skip the other configs for now
@@ -293,8 +314,6 @@ static bool canUseColorShader(const SkBitmap& bm, SkColor* color) {
return false;
}
-#include "SkTemplatesPriv.h"
-
static bool bitmapIsTooBig(const SkBitmap& bm) {
// SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it
// communicates between its matrix-proc and its sampler-proc. Until we can
@@ -305,27 +324,36 @@ static bool bitmapIsTooBig(const SkBitmap& bm) {
return bm.width() > maxSize || bm.height() > maxSize;
}
-SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
- TileMode tmx, TileMode tmy,
- void* storage, size_t storageSize) {
+SkShader* CreateBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
+ SkShader::TileMode tmy, const SkMatrix* localMatrix, SkTBlitterAllocator* allocator) {
SkShader* shader;
SkColor color;
if (src.isNull() || bitmapIsTooBig(src)) {
- SK_PLACEMENT_NEW(shader, SkEmptyShader, storage, storageSize);
+ if (NULL == allocator) {
+ shader = SkNEW(SkEmptyShader);
+ } else {
+ shader = allocator->createT<SkEmptyShader>();
+ }
}
else if (canUseColorShader(src, &color)) {
- SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize,
- (color));
+ if (NULL == allocator) {
+ shader = SkNEW_ARGS(SkColorShader, (color));
+ } else {
+ shader = allocator->createT<SkColorShader>(color);
+ }
} else {
- SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage,
- storageSize, (src, tmx, tmy));
+ if (NULL == allocator) {
+ shader = SkNEW_ARGS(SkBitmapProcShader, (src, tmx, tmy, localMatrix));
+ } else {
+ shader = allocator->createT<SkBitmapProcShader>(src, tmx, tmy, localMatrix);
+ }
}
return shader;
}
///////////////////////////////////////////////////////////////////////////////
-#ifdef SK_DEVELOPER
+#ifndef SK_IGNORE_TO_STRING
void SkBitmapProcShader::toString(SkString* str) const {
static const char* gTileModeName[SkShader::kTileModeCount] = {
"clamp", "repeat", "mirror"
@@ -334,8 +362,8 @@ void SkBitmapProcShader::toString(SkString* str) const {
str->append("BitmapShader: (");
str->appendf("(%s, %s)",
- gTileModeName[fState.fTileModeX],
- gTileModeName[fState.fTileModeY]);
+ gTileModeName[fTileModeX],
+ gTileModeName[fTileModeY]);
str->append(" ");
fRawBitmap.toString(str);
@@ -354,51 +382,60 @@ void SkBitmapProcShader::toString(SkString* str) const {
#include "effects/GrSimpleTextureEffect.h"
#include "SkGr.h"
-GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
+bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
+ const SkMatrix* localMatrix, GrColor* grColor,
+ GrEffectRef** grEffect) const {
SkMatrix matrix;
matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height());
- SkMatrix inverse;
- if (!this->getLocalMatrix().invert(&inverse)) {
- return NULL;
+ SkMatrix lmInverse;
+ if (!this->getLocalMatrix().invert(&lmInverse)) {
+ return false;
}
- matrix.preConcat(inverse);
+ if (localMatrix) {
+ SkMatrix inv;
+ if (!localMatrix->invert(&inv)) {
+ return false;
+ }
+ lmInverse.postConcat(inv);
+ }
+ matrix.preConcat(lmInverse);
SkShader::TileMode tm[] = {
- (TileMode)fState.fTileModeX,
- (TileMode)fState.fTileModeY,
+ (TileMode)fTileModeX,
+ (TileMode)fTileModeY,
};
- // Must set wrap and filter on the sampler before requesting a texture.
- SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel();
+ // Must set wrap and filter on the sampler before requesting a texture. In two places below
+ // we check the matrix scale factors to determine how to interpret the filter quality setting.
+ // This completely ignores the complexity of the drawVertices case where explicit local coords
+ // are provided by the caller.
+ bool useBicubic = false;
GrTextureParams::FilterMode textureFilterMode;
- switch(paintFilterLevel) {
+ switch(paint.getFilterLevel()) {
case SkPaint::kNone_FilterLevel:
textureFilterMode = GrTextureParams::kNone_FilterMode;
break;
case SkPaint::kLow_FilterLevel:
textureFilterMode = GrTextureParams::kBilerp_FilterMode;
break;
- case SkPaint::kMedium_FilterLevel:
- textureFilterMode = GrTextureParams::kMipMap_FilterMode;
- break;
- case SkPaint::kHigh_FilterLevel:
- // Minification can look bad with the bicubic effect. This is an overly aggressive
- // check for MIP fallbacks. It doesn't consider the fact that minification in the local
- // matrix could be offset by the view matrix and vice versa. We also don't know whether
- // the draw has explicit local coords (e.g. drawVertices) where the scale factor is
- // unknown and varies.
- if (context->getMatrix().getMinStretch() >= SK_Scalar1 &&
- this->getLocalMatrix().getMaxStretch() <= SK_Scalar1) {
- // fall back to no filtering here; we will install another
- // shader that will do the HQ filtering.
- textureFilterMode = GrTextureParams::kNone_FilterMode;
- } else {
- // Fall back to mip-mapping.
- paintFilterLevel = SkPaint::kMedium_FilterLevel;
+ case SkPaint::kMedium_FilterLevel: {
+ SkMatrix matrix;
+ matrix.setConcat(context->getMatrix(), this->getLocalMatrix());
+ if (matrix.getMinScale() < SK_Scalar1) {
textureFilterMode = GrTextureParams::kMipMap_FilterMode;
+ } else {
+ // Don't trigger MIP level generation unnecessarily.
+ textureFilterMode = GrTextureParams::kBilerp_FilterMode;
}
break;
+ }
+ case SkPaint::kHigh_FilterLevel: {
+ SkMatrix matrix;
+ matrix.setConcat(context->getMatrix(), this->getLocalMatrix());
+ useBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
+ break;
+ }
default:
SkErrorInternals::SetError( kInvalidPaint_SkError,
"Sorry, I don't understand the filtering "
@@ -414,16 +451,29 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint&
if (NULL == texture) {
SkErrorInternals::SetError( kInternalError_SkError,
"Couldn't convert bitmap to texture.");
- return NULL;
+ return false;
}
+
+ *grColor = (kAlpha_8_SkColorType == fRawBitmap.colorType()) ? SkColor2GrColor(paint.getColor())
+ : SkColor2GrColorJustAlpha(paint.getColor());
- GrEffectRef* effect = NULL;
- if (paintFilterLevel == SkPaint::kHigh_FilterLevel) {
- effect = GrBicubicEffect::Create(texture, matrix, tm);
+ if (useBicubic) {
+ *grEffect = GrBicubicEffect::Create(texture, matrix, tm);
} else {
- effect = GrSimpleTextureEffect::Create(texture, matrix, params);
+ *grEffect = GrSimpleTextureEffect::Create(texture, matrix, params);
}
GrUnlockAndUnrefCachedBitmapTexture(texture);
- return effect;
+
+ return true;
}
+
+#else
+
+bool SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint,
+ const SkMatrix* localMatrix, GrColor* grColor,
+ GrEffectRef** grEffect) const {
+ SkDEBUGFAIL("Should not call in GPU-less build");
+ return false;
+}
+
#endif