diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-27 00:09:42 +0000 |
commit | ae2c20f398933a9e86c387dcc465ec0f71065ffc (patch) | |
tree | de668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkBitmapProcShader.cpp | |
parent | 09911bf300f1a419907a9412154760efd0b7abc3 (diff) | |
download | chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.zip chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.gz chromium_src-ae2c20f398933a9e86c387dcc465ec0f71065ffc.tar.bz2 |
Add skia to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/sgl/SkBitmapProcShader.cpp')
-rw-r--r-- | skia/sgl/SkBitmapProcShader.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/skia/sgl/SkBitmapProcShader.cpp b/skia/sgl/SkBitmapProcShader.cpp new file mode 100644 index 0000000..8685c9f --- /dev/null +++ b/skia/sgl/SkBitmapProcShader.cpp @@ -0,0 +1,194 @@ +#include "SkBitmapProcShader.h" +#include "SkColorPriv.h" +#include "SkPixelRef.h" + +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: + // if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx)) + return true; + default: + break; + } + return false; +} + +SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, + TileMode tmx, TileMode tmy) { + fRawBitmap = src; + fState.fTileModeX = (uint8_t)tmx; + fState.fTileModeY = (uint8_t)tmy; +} + +SkBitmapProcShader::SkBitmapProcShader(SkFlattenableReadBuffer& buffer) + : INHERITED(buffer) { + fRawBitmap.unflatten(buffer); + fState.fTileModeX = buffer.readU8(); + fState.fTileModeY = buffer.readU8(); +} + +void SkBitmapProcShader::beginSession() { + this->INHERITED::beginSession(); + + fRawBitmap.lockPixels(); +} + +void SkBitmapProcShader::endSession() { + fRawBitmap.unlockPixels(); + + this->INHERITED::endSession(); +} + +bool SkBitmapProcShader::asABitmap(SkBitmap* texture, SkMatrix* texM, + TileMode xy[]) { + if (texture) { + *texture = fRawBitmap; + } + if (texM) { + texM->reset(); + } + if (xy) { + xy[0] = (TileMode)fState.fTileModeX; + xy[1] = (TileMode)fState.fTileModeY; + } + return true; +} + +void SkBitmapProcShader::flatten(SkFlattenableWriteBuffer& buffer) { + this->INHERITED::flatten(buffer); + + fRawBitmap.flatten(buffer); + buffer.write8(fState.fTileModeX); + buffer.write8(fState.fTileModeY); +} + +bool SkBitmapProcShader::setContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix) { + // do this first, so we have a correct inverse matrix + if (!this->INHERITED::setContext(device, paint, matrix)) { + return false; + } + + fState.fOrigBitmap = fRawBitmap; + fState.fOrigBitmap.lockPixels(); + if (fState.fOrigBitmap.getPixels() == NULL) { + fState.fOrigBitmap.unlockPixels(); + return false; + } + + if (!fState.chooseProcs(this->getTotalInverse(), paint)) { + return false; + } + + bool bitmapIsOpaque = fState.fBitmap->isOpaque(); + + // filtering doesn't guarantee that opaque stays opaque (finite precision) + // so pretend we're not opaque if we're being asked to filter. If we had + // more blit-procs, we could specialize on opaque src, and just OR in 0xFF + // after the filter to be sure... + if (paint.isFilterBitmap()) { + bitmapIsOpaque = false; + } + + // update fFlags + fFlags = 0; // this should happen in SkShader.cpp + + if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { + fFlags |= kOpaqueAlpha_Flag; + } + + switch (fState.fBitmap->config()) { + case SkBitmap::kRGB_565_Config: + fFlags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); + break; + case SkBitmap::kIndex8_Config: + case SkBitmap::kARGB_8888_Config: + if (bitmapIsOpaque) { + fFlags |= kHasSpan16_Flag; + } + break; + case SkBitmap::kA8_Config: + break; // never set kHasSpan16_Flag + default: + break; + } + return true; +} + +#define BUF_MAX 128 + +void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { + uint32_t buffer[BUF_MAX]; + + const SkBitmapProcState& state = fState; + SkBitmapProcState::MatrixProc mproc = state.fMatrixProc; + SkBitmapProcState::SampleProc32 sproc = state.fSampleProc32; + int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX; + + SkASSERT(state.fBitmap->getPixels()); + SkASSERT(state.fBitmap->pixelRef() == NULL || + state.fBitmap->pixelRef()->getLockCount()); + + for (;;) { + int n = count; + if (n > max) { + n = max; + } + mproc(state, buffer, n, x, y); + sproc(state, buffer, n, dstC); + + if ((count -= n) == 0) { + break; + } + x += n; + dstC += n; + } +} + +void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { + uint32_t buffer[BUF_MAX]; + + const SkBitmapProcState& state = fState; + SkBitmapProcState::MatrixProc mproc = state.fMatrixProc; + SkBitmapProcState::SampleProc16 sproc = state.fSampleProc16; + int max = fState.fDoFilter ? (BUF_MAX >> 1) : BUF_MAX; + + SkASSERT(state.fBitmap->getPixels()); + SkASSERT(state.fBitmap->pixelRef() == NULL || + state.fBitmap->pixelRef()->getLockCount()); + + for (;;) { + int n = count; + if (n > max) { + n = max; + } + mproc(state, buffer, n, x, y); + sproc(state, buffer, n, dstC); + + if ((count -= n) == 0) { + break; + } + x += n; + dstC += n; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +#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)); + return shader; +} + +static SkFlattenable::Registrar gBitmapProcShaderReg("SkBitmapProcShader", + SkBitmapProcShader::CreateProc); |