summaryrefslogtreecommitdiffstats
path: root/skia/sgl/SkBitmapProcShader.cpp
diff options
context:
space:
mode:
authorinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
committerinitial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98>2008-07-27 00:09:42 +0000
commitae2c20f398933a9e86c387dcc465ec0f71065ffc (patch)
treede668b1411e2ee0b4e49b6d8f8b68183134ac990 /skia/sgl/SkBitmapProcShader.cpp
parent09911bf300f1a419907a9412154760efd0b7abc3 (diff)
downloadchromium_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.cpp194
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);