180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBitmapProcShader.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPixelRef.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) { 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (bm.config()) { 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kA8_Config: 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kRGB_565_Config: 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kIndex8_Config: 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kARGB_8888_Config: 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx)) 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TileMode tmx, TileMode tmy) { 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fRawBitmap = src; 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fTileModeX = (uint8_t)tmx; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fTileModeY = (uint8_t)tmy; 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = 0; // computed in setContext 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkBitmapProcShader::SkBitmapProcShader(SkFlattenableReadBuffer& buffer) 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : INHERITED(buffer) { 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.readBitmap(&fRawBitmap); 38363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fRawBitmap.setImmutable(); 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fTileModeX = buffer.readUInt(); 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fTileModeY = buffer.readUInt(); 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = 0; // computed in setContext 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix* texM, 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TileMode xy[]) const { 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (texture) { 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *texture = fRawBitmap; 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (texM) { 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru texM->reset(); 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (xy) { 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru xy[0] = (TileMode)fState.fTileModeX; 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru xy[1] = (TileMode)fState.fTileModeY; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return kDefault_BitmapType; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkBitmapProcShader::flatten(SkFlattenableWriteBuffer& buffer) const { 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->INHERITED::flatten(buffer); 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeBitmap(fRawBitmap); 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeUInt(fState.fTileModeX); 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer.writeUInt(fState.fTileModeY); 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool only_scale_and_translate(const SkMatrix& matrix) { 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (matrix.getType() & ~mask) == 0; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkBitmapProcShader::isOpaque() const { 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return fRawBitmap.isOpaque(); 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkBitmapProcShader::setContext(const SkBitmap& device, 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPaint& paint, 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkMatrix& matrix) { 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // do this first, so we have a correct inverse matrix 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!this->INHERITED::setContext(device, paint, matrix)) { 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fOrigBitmap = fRawBitmap; 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fOrigBitmap.lockPixels(); 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fState.fOrigBitmap.getTexture() && !fState.fOrigBitmap.readyToDraw()) { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fState.fOrigBitmap.unlockPixels(); 89d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::endContext(); 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fState.chooseProcs(this->getTotalInverse(), paint)) { 94363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fState.fOrigBitmap.unlockPixels(); 95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::endContext(); 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmap& bitmap = *fState.fBitmap; 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool bitmapIsOpaque = bitmap.isOpaque(); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // update fFlags 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t flags = 0; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags |= kOpaqueAlpha_Flag; 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (bitmap.config()) { 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kRGB_565_Config: 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kIndex8_Config: 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kARGB_8888_Config: 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bitmapIsOpaque) { 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags |= kHasSpan16_Flag; 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kA8_Config: 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; // never set kHasSpan16_Flag 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (paint.isDither() && bitmap.config() != SkBitmap::kRGB_565_Config) { 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // gradients can auto-dither in their 16bit sampler, but we don't so 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we clear the flag here. 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags &= ~kHasSpan16_Flag; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // if we're only 1-pixel high, and we don't rotate, then we can claim this 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (1 == bitmap.height() && 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru only_scale_and_translate(this->getTotalInverse())) { 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags |= kConstInY32_Flag; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (flags & kHasSpan16_Flag) { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru flags |= kConstInY16_Flag; 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fFlags = flags; 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkBitmapProcShader::endContext() { 144363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fState.fOrigBitmap.unlockPixels(); 145363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->INHERITED::endContext(); 146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger} 147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define BUF_MAX 128 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define TEST_BUFFER_OVERRITEx 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef TEST_BUFFER_OVERRITE 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define TEST_BUFFER_EXTRA 32 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define TEST_PATTERN 0x88888888 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define TEST_BUFFER_EXTRA 0 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmapProcState& state = fState; 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (state.getShaderProc32()) { 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru state.getShaderProc32()(state, x, y, dstC, count); 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(state.fBitmap->getPixels()); 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(state.fBitmap->pixelRef() == NULL || 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru state.fBitmap->pixelRef()->isLocked()); 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (;;) { 17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = count; 17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n > max) { 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = max; 17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(n > 0 && n < BUF_MAX*2); 18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef TEST_BUFFER_OVERRITE 18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < TEST_BUFFER_EXTRA; i++) { 18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru buffer[BUF_MAX + i] = TEST_PATTERN; 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mproc(state, buffer, n, x, y); 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef TEST_BUFFER_OVERRITE 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int j = 0; j < TEST_BUFFER_EXTRA; j++) { 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(buffer[BUF_MAX + j] == TEST_PATTERN); 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sproc(state, buffer, n, dstC); 19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((count -= n) == 0) { 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(count > 0); 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x += n; 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstC += n; 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fState.getShaderProc32()) { 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *ctx = &fState; 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (ShadeProc)fState.getShaderProc32(); 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkBitmapProcState& state = fState; 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (state.getShaderProc16()) { 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru state.getShaderProc16()(state, x, y, dstC, count); 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return; 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru uint32_t buffer[BUF_MAX]; 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int max = fState.maxCountForBufferSize(sizeof(buffer)); 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(state.fBitmap->getPixels()); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(state.fBitmap->pixelRef() == NULL || 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru state.fBitmap->pixelRef()->isLocked()); 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (;;) { 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = count; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n > max) { 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = max; 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mproc(state, buffer, n, x, y); 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sproc(state, buffer, n, dstC); 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((count -= n) == 0) { 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x += n; 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dstC += n; 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkUnPreMultiply.h" 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorShader.h" 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkEmptyShader.h" 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// returns true and set color if the bitmap can be drawn as a single color 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// (for efficiency) 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool canUseColorShader(const SkBitmap& bm, SkColor* color) { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (1 != bm.width() || 1 != bm.height()) { 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkAutoLockPixels alp(bm); 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!bm.readyToDraw()) { 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (bm.config()) { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kARGB_8888_Config: 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0)); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kRGB_565_Config: 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *color = SkPixel16ToColor(*bm.getAddr16(0, 0)); 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case SkBitmap::kIndex8_Config: 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0)); 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: // just skip the other configs for now 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTemplatesPriv.h" 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool bitmapIsTooBig(const SkBitmap& bm) { 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // communicates between its matrix-proc and its sampler-proc. Until we can 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // widen that, we have to reject bitmaps that are larger. 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const int maxSize = 65535; 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return bm.width() > maxSize || bm.height() > maxSize; 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TileMode tmx, TileMode tmy, 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru void* storage, size_t storageSize) { 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkShader* shader; 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkColor color; 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src.isNull() || bitmapIsTooBig(src)) { 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_PLACEMENT_NEW(shader, SkEmptyShader, storage, storageSize); 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru else if (canUseColorShader(src, &color)) { 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize, 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (color)); 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru storageSize, (src, tmx, tmy)); 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return shader; 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 309d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 310d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkBitmapProcShader::toString(SkString* str) const { 311d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger static const char* gTileModeName[SkShader::kTileModeCount] = { 312d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger "clamp", "repeat", "mirror" 313d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger }; 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 315d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append("BitmapShader: ("); 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 317d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->appendf("(%s, %s)", 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gTileModeName[fState.fTileModeX], 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gTileModeName[fState.fTileModeY]); 320d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 321d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(" "); 322d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger fRawBitmap.toString(str); 323d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 324d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->INHERITED::toString(str); 325d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 326d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->append(")"); 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 328d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 329d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 330d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 331d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 332d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#if SK_SUPPORT_GPU 333d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 334d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "GrTextureAccess.h" 335d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "effects/GrSimpleTextureEffect.h" 336d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkGr.h" 337d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 338d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const { 339d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkMatrix matrix; 340d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); 341d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 342d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (this->hasLocalMatrix()) { 343d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkMatrix inverse; 344d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!this->getLocalMatrix().invert(&inverse)) { 345d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 346d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 347d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger matrix.preConcat(inverse); 348d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 349d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkShader::TileMode tm[] = { 350d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger (TileMode)fState.fTileModeX, 351d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger (TileMode)fState.fTileModeY, 352d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger }; 353d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 354d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Must set wrap and filter on the sampler before requesting a texture. 355d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTextureParams params(tm, paint.isFilterBitmap()); 356d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrTexture* texture = GrLockAndRefCachedBitmapTexture(context, fRawBitmap, ¶ms); 357d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 358d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (NULL == texture) { 359d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkDebugf("Couldn't convert bitmap to texture.\n"); 360d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return NULL; 361d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 363d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); 364d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrUnlockAndUnrefCachedBitmapTexture(texture); 365d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return effect; 366d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 367d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 368