// The info has been allocated elsewhere, but we are responsible for calling its destructor. BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec, SkBitmapProcInfo* info) : INHERITED(shader, rec) , fInfo(info) { fFlags = 0; if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { fFlags |= SkShader::kOpaqueAlpha_Flag; } if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { fFlags |= SkShader::kConstInY32_Flag; } }
SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext(const SkShader& shader, const ContextRec& rec, SkBitmapProcState* state) : INHERITED(shader, rec) , fState(state) { const SkPixmap& pixmap = fState->fPixmap; bool isOpaque = pixmap.isOpaque(); // update fFlags uint32_t flags = 0; if (isOpaque && (255 == this->getPaintAlpha())) { flags |= kOpaqueAlpha_Flag; } switch (pixmap.colorType()) { case kRGB_565_SkColorType: flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); break; case kIndex_8_SkColorType: case kN32_SkColorType: if (isOpaque) { flags |= kHasSpan16_Flag; } break; case kAlpha_8_SkColorType: break; // never set kHasSpan16_Flag default: break; } if (rec.fPaint->isDither() && pixmap.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; } // if we're only 1-pixel high, and we don't rotate, then we can claim this if (1 == pixmap.height() && only_scale_and_translate(this->getTotalInverse())) { flags |= kConstInY32_Flag; if (flags & kHasSpan16_Flag) { flags |= kConstInY16_Flag; } } fFlags = flags; }
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; }