SkShader::Context* SkBitmapProcShader::onCreateContext(const ContextRec& rec, void* storage) const { if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { return NULL; } SkMatrix totalInverse; // Do this first, so we know the matrix can be inverted. if (!this->computeTotalInverse(rec, &totalInverse)) { return NULL; } 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; } return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, rec, state)); }
SkBitmapController::State* SkBitmapController::requestBitmap(const SkBitmap& bm, const SkMatrix& inv, SkFilterQuality quality, void* storage, size_t storageSize) { if (!valid_for_drawing(bm)) { return NULL; } State* state = this->onRequestBitmap(bm, inv, quality, storage, storageSize); if (state) { if (NULL == state->fPixmap.addr()) { SkInPlaceDeleteCheck(state, storage); state = NULL; } } return state; }
bool SkBitmapProcShader::setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) { if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { return false; } // do this first, so we have a correct inverse matrix if (!this->INHERITED::setContext(device, paint, matrix)) { return false; } fState.fOrigBitmap = fRawBitmap; if (!fState.chooseProcs(this->getTotalInverse(), paint)) { this->INHERITED::endContext(); return false; } const SkBitmap& bitmap = *fState.fBitmap; bool bitmapIsOpaque = bitmap.isOpaque(); // update fFlags uint32_t flags = 0; if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { flags |= kOpaqueAlpha_Flag; } switch (bitmap.config()) { case SkBitmap::kRGB_565_Config: flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); break; case SkBitmap::kIndex8_Config: case SkBitmap::kARGB_8888_Config: if (bitmapIsOpaque) { flags |= kHasSpan16_Flag; } break; case SkBitmap::kA8_Config: break; // never set kHasSpan16_Flag default: break; } if (paint.isDither() && bitmap.config() != SkBitmap::kRGB_565_Config) { // 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 high, and we don't rotate, then we can claim this if (1 == bitmap.height() && only_scale_and_translate(this->getTotalInverse())) { flags |= kConstInY32_Flag; if (flags & kHasSpan16_Flag) { flags |= kConstInY16_Flag; } } fFlags = flags; return true; }