本文整理汇总了C++中SkIRect::intersect方法的典型用法代码示例。如果您正苦于以下问题:C++ SkIRect::intersect方法的具体用法?C++ SkIRect::intersect怎么用?C++ SkIRect::intersect使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SkIRect
的用法示例。
在下文中一共展示了SkIRect::intersect方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: setupClipping
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType;
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
}
GrReducedClip::ElementList elements(16);
int32_t genID = 0;
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds;
bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
const GrClip& clip = pipelineBuilder->clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
// The clip mask manager always draws with a single IRect so we special case that logic here
// Image filters just use a rect, so we also special case that logic
switch (clip.clipType()) {
case GrClip::kWideOpen_ClipType:
SkFAIL("Should have caught this with clip.isWideOpen()");
return true;
case GrClip::kIRect_ClipType: {
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
scissorState->set(scissor);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
}
case GrClip::kClipStack_ClipType: {
clipSpaceRTIBounds.offset(clip.origin());
GrReducedClip::ReduceClipStack(*clip.clipStack(),
clipSpaceRTIBounds,
&elements,
&genID,
&initialState,
&clipSpaceIBounds,
&requiresAA);
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
return false;
}
}
}
break;
}
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
// isect convex_poly
// isect convex_poly
// when drawing rounded div borders. This could probably be tuned based on a
// configuration's relative costs of switching RTs to generate a mask vs
// longer shaders.
if (elements.count() <= 4) {
SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
SkIntToScalar(-clip.origin().fY)
};
if (elements.isEmpty() ||
(requiresAA && this->installClipEffects(pipelineBuilder, arfp, elements, clipToRTOffset,
devBounds))) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
if (NULL == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
scissorState->set(scissorSpaceIBounds);
}
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
}
// If MSAA is enabled we can do everything in the stencil buffer.
if (0 == rt->numSamples() && requiresAA) {
GrTexture* result = NULL;
// The top-left of the mask corresponds to the top-left corner of the bounds.
SkVector clipToMaskOffset = {
//.........这里部分代码省略.........
示例2: setupDstReadIfNecessary
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
const GrProcOptInfo& colorPOI,
const GrProcOptInfo& coveragePOI,
GrXferProcessor::DstTexture* dstTexture,
const SkRect* drawBounds) {
if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), colorPOI, coveragePOI)) {
return true;
}
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
if (this->caps()->textureBarrierSupport()) {
if (GrTexture* rtTex = rt->asTexture()) {
// The render target is a texture, so we can read from it directly in the shader. The XP
// will be responsible to detect this situation and request a texture barrier.
dstTexture->setTexture(rtTex);
dstTexture->setOffset(0, 0);
return true;
}
}
SkIRect copyRect;
pipelineBuilder.clip().getConservativeBounds(rt, ©Rect);
if (drawBounds) {
SkIRect drawIBounds;
drawBounds->roundOut(&drawIBounds);
if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
GrCapsDebugf(fCaps, "Missed an early reject. "
"Bailing on draw from setupDstReadIfNecessary.\n");
#endif
return false;
}
} else {
#ifdef SK_DEBUG
//SkDebugf("No dev bounds when dst copy is made.\n");
#endif
}
// MSAA consideration: When there is support for reading MSAA samples in the shader we could
// have per-sample dst values by making the copy multisampled.
GrSurfaceDesc desc;
if (!this->getGpu()->initCopySurfaceDstDesc(rt, &desc)) {
desc.fOrigin = kDefault_GrSurfaceOrigin;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = rt->config();
}
desc.fWidth = copyRect.width();
desc.fHeight = copyRect.height();
SkAutoTUnref<GrTexture> copy(
fResourceProvider->refScratchTexture(desc, GrTextureProvider::kApprox_ScratchTexMatch));
if (!copy) {
SkDebugf("Failed to create temporary copy of destination texture.\n");
return false;
}
SkIPoint dstPoint = {0, 0};
this->copySurface(copy, rt, copyRect, dstPoint);
dstTexture->setTexture(copy);
dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
return true;
}
示例3: draw
void draw(SkCanvas* canvas) {
SkIRect result;
bool intersected = result.intersect({ 10, 40, 50, 80 }, { 30, 60, 70, 90 });
SkDebugf("%s intersection: %d, %d, %d, %d\n", intersected ? "" : "no ",
result.left(), result.top(), result.right(), result.bottom());
}
示例4: blitClippedRect
static void blitClippedRect(SkBlitter* blitter, const SkIRect& rect, const SkIRect& clipR) {
SkIRect r;
if (r.intersect(rect, clipR)) {
blitter->blitRect(r.left(), r.top(), r.width(), r.height());
}
}
示例5: draw_nine_clipped
static void draw_nine_clipped(const SkMask& mask, const SkIRect& outerR,
const SkIPoint& center, bool fillCenter,
const SkIRect& clipR, SkBlitter* blitter) {
int cx = center.x();
int cy = center.y();
SkMask m;
// top-left
m.fBounds = mask.fBounds;
m.fBounds.fRight = cx;
m.fBounds.fBottom = cy;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.left(), outerR.top());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// top-right
m.fBounds = mask.fBounds;
m.fBounds.fLeft = cx + 1;
m.fBounds.fBottom = cy;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.right() - m.fBounds.width(), outerR.top());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// bottom-left
m.fBounds = mask.fBounds;
m.fBounds.fRight = cx;
m.fBounds.fTop = cy + 1;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.left(), outerR.bottom() - m.fBounds.height());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
// bottom-right
m.fBounds = mask.fBounds;
m.fBounds.fLeft = cx + 1;
m.fBounds.fTop = cy + 1;
if (m.fBounds.width() > 0 && m.fBounds.height() > 0) {
extractMaskSubset(mask, &m);
m.fBounds.offsetTo(outerR.right() - m.fBounds.width(),
outerR.bottom() - m.fBounds.height());
blitClippedMask(blitter, m, m.fBounds, clipR);
}
SkIRect innerR;
innerR.set(outerR.left() + cx - mask.fBounds.left(),
outerR.top() + cy - mask.fBounds.top(),
outerR.right() + (cx + 1 - mask.fBounds.right()),
outerR.bottom() + (cy + 1 - mask.fBounds.bottom()));
if (fillCenter) {
blitClippedRect(blitter, innerR, clipR);
}
const int innerW = innerR.width();
size_t storageSize = (innerW + 1) * (sizeof(int16_t) + sizeof(uint8_t));
SkAutoSMalloc<4*1024> storage(storageSize);
int16_t* runs = (int16_t*)storage.get();
uint8_t* alpha = (uint8_t*)(runs + innerW + 1);
SkIRect r;
// top
r.set(innerR.left(), outerR.top(), innerR.right(), innerR.top());
if (r.intersect(clipR)) {
int startY = SkMax32(0, r.top() - outerR.top());
int stopY = startY + r.height();
int width = r.width();
for (int y = startY; y < stopY; ++y) {
runs[0] = width;
runs[width] = 0;
alpha[0] = *mask.getAddr8(cx, mask.fBounds.top() + y);
blitter->blitAntiH(r.left(), outerR.top() + y, alpha, runs);
}
}
// bottom
r.set(innerR.left(), innerR.bottom(), innerR.right(), outerR.bottom());
if (r.intersect(clipR)) {
int startY = outerR.bottom() - r.bottom();
int stopY = startY + r.height();
int width = r.width();
for (int y = startY; y < stopY; ++y) {
runs[0] = width;
runs[width] = 0;
alpha[0] = *mask.getAddr8(cx, mask.fBounds.bottom() - y - 1);
blitter->blitAntiH(r.left(), outerR.bottom() - y - 1, alpha, runs);
}
}
// left
r.set(outerR.left(), innerR.top(), innerR.left(), innerR.bottom());
if (r.intersect(clipR)) {
int startX = r.left() - outerR.left();
int stopX = startX + r.width();
int height = r.height();
for (int x = startX; x < stopX; ++x) {
blitter->blitV(outerR.left() + x, r.top(), height,
*mask.getAddr8(mask.fBounds.left() + x, mask.fBounds.top() + cy));
}
//.........这里部分代码省略.........
示例6: drawBatch
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
const GrClip& clip,
GrDrawBatch* batch) {
// Setup clip
GrAppliedClip appliedClip;
if (!clip.apply(fClipMaskManager, pipelineBuilder, &batch->bounds(), &appliedClip)) {
return;
}
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
if (appliedClip.clipCoverageFragmentProcessor()) {
arfps.set(&pipelineBuilder);
arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor());
}
GrPipeline::CreateArgs args;
args.fPipelineBuilder = &pipelineBuilder;
args.fCaps = this->caps();
args.fScissor = &appliedClip.scissorState();
args.fHasStencilClip = appliedClip.hasStencilClip();
if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
if (!fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarget())) {
SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
return;
}
}
batch->getPipelineOptimizations(&args.fOpts);
GrScissorState finalScissor;
if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) {
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrGLIRect viewport;
viewport.fLeft = 0;
viewport.fBottom = 0;
viewport.fWidth = rt->width();
viewport.fHeight = rt->height();
SkIRect ibounds;
ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft,
viewport.fWidth);
ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom,
viewport.fHeight);
ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft,
viewport.fWidth);
ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
viewport.fHeight);
if (appliedClip.scissorState().enabled()) {
const SkIRect& scissorRect = appliedClip.scissorState().rect();
if (!ibounds.intersect(scissorRect)) {
return;
}
}
finalScissor.set(ibounds);
args.fScissor = &finalScissor;
}
args.fOpts.fColorPOI.completeCalculations(pipelineBuilder.fColorFragmentProcessors.begin(),
pipelineBuilder.numColorFragmentProcessors());
args.fOpts.fCoveragePOI.completeCalculations(
pipelineBuilder.fCoverageFragmentProcessors.begin(),
pipelineBuilder.numCoverageFragmentProcessors());
if (!this->setupDstReadIfNecessary(pipelineBuilder, clip, args.fOpts, &args.fDstTexture,
batch->bounds())) {
return;
}
if (!batch->installPipeline(args)) {
return;
}
#ifdef ENABLE_MDB
SkASSERT(fRenderTarget);
batch->pipeline()->addDependenciesTo(fRenderTarget);
#endif
this->recordBatch(batch);
}
示例7: setupClipping
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreStencil* ars,
const SkRect* devBounds,
GrAppliedClip* out) {
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
}
GrReducedClip::ElementList elements;
int32_t genID = 0;
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds;
bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
GrClip devBoundsClip;
bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
if (doDevBoundsClip) {
add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip);
}
const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
// The clip mask manager always draws with a single IRect so we special case that logic here
// Image filters just use a rect, so we also special case that logic
switch (clip.clipType()) {
case GrClip::kWideOpen_ClipType:
SkFAIL("Should have caught this with clip.isWideOpen()");
return true;
case GrClip::kIRect_ClipType: {
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
out->fScissorState.set(scissor);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
}
case GrClip::kClipStack_ClipType: {
clipSpaceRTIBounds.offset(clip.origin());
SkIRect clipSpaceReduceQueryBounds;
#define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
SkIRect devIBounds = devBounds->roundOut();
devIBounds.offset(clip.origin());
if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds)) {
return false;
}
} else {
clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
}
GrReducedClip::ReduceClipStack(*clip.clipStack(),
clipSpaceReduceQueryBounds,
&elements,
&genID,
&initialState,
&clipSpaceIBounds,
&requiresAA);
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
return false;
}
}
} break;
}
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
// isect convex_poly
// isect convex_poly
// when drawing rounded div borders. This could probably be tuned based on a
// configuration's relative costs of switching RTs to generate a mask vs
// longer shaders.
if (elements.count() <= kMaxAnalyticElements) {
SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
SkIntToScalar(-clip.origin().fY) };
// When there are multiple samples we want to do per-sample clipping, not compute a
// fractional pixel coverage.
bool disallowAnalyticAA = rt->isUnifiedMultisampled() || pipelineBuilder.hasMixedSamples();
const GrFragmentProcessor* clipFP = nullptr;
if (elements.isEmpty() ||
(requiresAA &&
this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipToRTOffset, devBounds,
//.........这里部分代码省略.........
示例8: filterImageGPU
bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
SkBitmap* result, SkIPoint* offset) const {
SkBitmap colorBM = src;
SkIPoint colorOffset = SkIPoint::Make(0, 0);
if (getColorInput() && !getColorInput()->getInputResultGPU(proxy, src, ctx, &colorBM,
&colorOffset)) {
return false;
}
SkBitmap displacementBM = src;
SkIPoint displacementOffset = SkIPoint::Make(0, 0);
if (getDisplacementInput() &&
!getDisplacementInput()->getInputResultGPU(proxy, src, ctx, &displacementBM,
&displacementOffset)) {
return false;
}
SkIRect bounds;
// Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to
// pad the color bitmap to bounds here.
if (!this->applyCropRect(ctx, colorBM, colorOffset, &bounds)) {
return false;
}
SkIRect displBounds;
if (!this->applyCropRect(ctx, proxy, displacementBM,
&displacementOffset, &displBounds, &displacementBM)) {
return false;
}
if (!bounds.intersect(displBounds)) {
return false;
}
GrTexture* color = colorBM.getTexture();
GrTexture* displacement = displacementBM.getTexture();
GrContext* context = color->getContext();
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = bounds.width();
desc.fHeight = bounds.height();
desc.fConfig = kSkia8888_GrPixelConfig;
SkAutoTUnref<GrTexture> dst(context->textureProvider()->refScratchTexture(desc,
GrTextureProvider::kApprox_ScratchTexMatch));
if (!dst) {
return false;
}
SkVector scale = SkVector::Make(fScale, fScale);
ctx.ctm().mapVectors(&scale, 1);
GrPaint paint;
SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacement);
offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.fX),
SkIntToScalar(colorOffset.fY - displacementOffset.fY));
paint.addColorProcessor(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
scale,
displacement,
offsetMatrix,
color,
colorBM.dimensions()))->unref();
SkIRect colorBounds = bounds;
colorBounds.offset(-colorOffset);
SkMatrix matrix;
matrix.setTranslate(-SkIntToScalar(colorBounds.x()),
-SkIntToScalar(colorBounds.y()));
context->drawRect(dst->asRenderTarget(), GrClip::WideOpen(), paint, matrix,
SkRect::Make(colorBounds));
offset->fX = bounds.left();
offset->fY = bounds.top();
WrapTexture(dst, bounds.width(), bounds.height(), result);
return true;
}
示例9: setupDstReadIfNecessary
bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
const GrClip& clip,
const GrPipelineOptimizations& optimizations,
GrXferProcessor::DstTexture* dstTexture,
const SkRect& batchBounds) {
SkRect bounds = batchBounds;
bounds.outset(0.5f, 0.5f);
if (!pipelineBuilder.willXPNeedDstTexture(*this->caps(), optimizations)) {
return true;
}
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
if (this->caps()->textureBarrierSupport()) {
if (GrTexture* rtTex = rt->asTexture()) {
// The render target is a texture, so we can read from it directly in the shader. The XP
// will be responsible to detect this situation and request a texture barrier.
dstTexture->setTexture(rtTex);
dstTexture->setOffset(0, 0);
return true;
}
}
SkIRect copyRect;
clip.getConservativeBounds(rt->width(), rt->height(), ©Rect);
SkIRect drawIBounds;
bounds.roundOut(&drawIBounds);
if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
GrCapsDebugf(this->caps(), "Missed an early reject. "
"Bailing on draw from setupDstReadIfNecessary.\n");
#endif
return false;
}
// MSAA consideration: When there is support for reading MSAA samples in the shader we could
// have per-sample dst values by making the copy multisampled.
GrSurfaceDesc desc;
if (!fGpu->initCopySurfaceDstDesc(rt, &desc)) {
desc.fOrigin = kDefault_GrSurfaceOrigin;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = rt->config();
}
desc.fWidth = copyRect.width();
desc.fHeight = copyRect.height();
static const uint32_t kFlags = 0;
SkAutoTUnref<GrTexture> copy(fResourceProvider->createApproxTexture(desc, kFlags));
if (!copy) {
SkDebugf("Failed to create temporary copy of destination texture.\n");
return false;
}
SkIPoint dstPoint = {0, 0};
this->copySurface(copy, rt, copyRect, dstPoint);
dstTexture->setTexture(copy);
dstTexture->setOffset(copyRect.fLeft, copyRect.fTop);
return true;
}
示例10: onDecodeRegion
bool SkJPEGImageDecoder::onDecodeRegion(SkBitmap* bm, SkIRect region) {
if (index == NULL) {
return false;
}
jpeg_decompress_struct *cinfo = index->cinfo;
SkIRect rect = SkIRect::MakeWH(this->imageWidth, this->imageHeight);
if (!rect.intersect(region)) {
// If the requested region is entirely outsides the image, just
// returns false
return false;
}
SkAutoMalloc srcStorage;
skjpeg_error_mgr sk_err;
cinfo->err = jpeg_std_error(&sk_err);
sk_err.error_exit = skjpeg_error_exit;
if (setjmp(sk_err.fJmpBuf)) {
return false;
}
int requestedSampleSize = this->getSampleSize();
cinfo->scale_denom = requestedSampleSize;
if (this->getPreferQualityOverSpeed()) {
cinfo->dct_method = JDCT_ISLOW;
} else {
cinfo->dct_method = JDCT_IFAST;
}
SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
if (config != SkBitmap::kARGB_8888_Config &&
config != SkBitmap::kARGB_4444_Config &&
config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
/* default format is RGB */
cinfo->out_color_space = JCS_RGB;
#ifdef ANDROID_RGB
cinfo->dither_mode = JDITHER_NONE;
if (config == SkBitmap::kARGB_8888_Config) {
cinfo->out_color_space = JCS_RGBA_8888;
} else if (config == SkBitmap::kRGB_565_Config) {
cinfo->out_color_space = JCS_RGB_565;
if (this->getDitherImage()) {
cinfo->dither_mode = JDITHER_ORDERED;
}
}
#endif
int startX = rect.fLeft;
int startY = rect.fTop;
int width = rect.width();
int height = rect.height();
jpeg_init_read_tile_scanline(cinfo, index->index,
&startX, &startY, &width, &height);
int skiaSampleSize = recompute_sampleSize(requestedSampleSize, *cinfo);
int actualSampleSize = skiaSampleSize * (DCTSIZE / cinfo->min_DCT_scaled_size);
SkBitmap *bitmap = new SkBitmap;
SkAutoTDelete<SkBitmap> adb(bitmap);
#ifdef ANDROID_RGB
/* short-circuit the SkScaledBitmapSampler when possible, as this gives
a significant performance boost.
*/
if (skiaSampleSize == 1 &&
((config == SkBitmap::kARGB_8888_Config &&
cinfo->out_color_space == JCS_RGBA_8888) ||
(config == SkBitmap::kRGB_565_Config &&
cinfo->out_color_space == JCS_RGB_565)))
{
bitmap->setConfig(config, cinfo->output_width, height);
bitmap->setIsOpaque(true);
// Check ahead of time if the swap(dest, src) is possible or not.
// If yes, then we will stick to AllocPixelRef since it's cheaper
// with the swap happening. If no, then we will use alloc to allocate
// pixels to prevent garbage collection.
//
// Not using a recycled-bitmap and the output rect is same as the
// decoded region.
int w = rect.width() / actualSampleSize;
int h = rect.height() / actualSampleSize;
bool swapOnly = (rect == region) && bm->isNull() &&
(w == bitmap->width()) && (h == bitmap->height()) &&
((startX - rect.x()) / actualSampleSize == 0) &&
((startY - rect.y()) / actualSampleSize == 0);
if (swapOnly) {
if (!this->allocPixelRef(bitmap, NULL)) {
return return_false(*cinfo, *bitmap, "allocPixelRef");
}
} else {
if (!bitmap->allocPixels()) {
return return_false(*cinfo, *bitmap, "allocPixels");
}
}
SkAutoLockPixels alp(*bitmap);
JSAMPLE* rowptr = (JSAMPLE*)bitmap->getPixels();
//.........这里部分代码省略.........
示例11: sizeof
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
static const int kW = 10;
static const int kH = 10;
static const size_t kRowBytes = sizeof(uint32_t) * kW;
GrSurfaceDesc baseDesc;
baseDesc.fConfig = kRGBA_8888_GrPixelConfig;
baseDesc.fWidth = kW;
baseDesc.fHeight = kH;
SkAutoTMalloc<uint32_t> srcPixels(kW * kH);
for (int i = 0; i < kW * kH; ++i) {
srcPixels.get()[i] = i;
}
SkAutoTMalloc<uint32_t> dstPixels(kW * kH);
for (int i = 0; i < kW * kH; ++i) {
dstPixels.get()[i] = ~i;
}
static const SkIRect kSrcRects[] {
{ 0, 0, kW , kH },
{-1, -1, kW+1, kH+1},
{ 1, 1, kW-1, kH-1},
{ 5, 5, 6 , 6 },
};
static const SkIPoint kDstPoints[] {
{ 0 , 0 },
{ 1 , 1 },
{ kW/2, kH/4},
{ kW-1, kH-1},
{ kW , kH },
{ kW+1, kH+2},
{-1 , -1 },
};
SkAutoTMalloc<uint32_t> read(kW * kH);
for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
for (auto dOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) {
for (auto sFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
for (auto dFlags: {kRenderTarget_GrSurfaceFlag, kNone_GrSurfaceFlags}) {
for (auto srcRect : kSrcRects) {
for (auto dstPoint : kDstPoints) {
GrSurfaceDesc srcDesc = baseDesc;
srcDesc.fOrigin = sOrigin;
srcDesc.fFlags = sFlags;
GrSurfaceDesc dstDesc = baseDesc;
dstDesc.fOrigin = dOrigin;
dstDesc.fFlags = dFlags;
SkAutoTUnref<GrTexture> src(
context->textureProvider()->createTexture(srcDesc, SkBudgeted::kNo,
srcPixels.get(),
kRowBytes));
SkAutoTUnref<GrTexture> dst(
context->textureProvider()->createTexture(dstDesc, SkBudgeted::kNo,
dstPixels.get(),
kRowBytes));
if (!src || !dst) {
ERRORF(reporter,
"Could not create surfaces for copy surface test.");
continue;
}
bool result = context->copySurface(dst, src, srcRect, dstPoint);
bool expectedResult = true;
SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft,
dstPoint.fY - srcRect.fTop };
SkIRect copiedDstRect = SkIRect::MakeXYWH(dstPoint.fX,
dstPoint.fY,
srcRect.width(),
srcRect.height());
SkIRect copiedSrcRect;
if (!copiedSrcRect.intersect(srcRect, SkIRect::MakeWH(kW, kH))) {
expectedResult = false;
} else {
// If the src rect was clipped, apply same clipping to each side of
// copied dst rect.
copiedDstRect.fLeft += copiedSrcRect.fLeft - srcRect.fLeft;
copiedDstRect.fTop += copiedSrcRect.fTop - srcRect.fTop;
copiedDstRect.fRight -= copiedSrcRect.fRight - srcRect.fRight;
copiedDstRect.fBottom -= copiedSrcRect.fBottom - srcRect.fBottom;
}
if (copiedDstRect.isEmpty() ||
!copiedDstRect.intersect(SkIRect::MakeWH(kW, kH))) {
expectedResult = false;
}
// To make the copied src rect correct we would apply any dst clipping
// back to the src rect, but we don't use it again so don't bother.
if (expectedResult != result) {
ERRORF(reporter, "Expected return value %d from copySurface, got "
"%d.", expectedResult, result);
continue;
}
//.........这里部分代码省略.........
示例12: onFilterImage
bool SkBlurImageFilter::onFilterImage(Proxy* proxy,
const SkBitmap& source, const Context& ctx,
SkBitmap* dst, SkIPoint* offset) const {
SkBitmap src = source;
SkIPoint srcOffset = SkIPoint::Make(0, 0);
if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) {
return false;
}
if (src.colorType() != kN32_SkColorType) {
return false;
}
SkIRect srcBounds = src.bounds();
srcBounds.offset(srcOffset);
SkIRect dstBounds;
if (!this->applyCropRect(this->mapContext(ctx), srcBounds, &dstBounds)) {
return false;
}
if (!srcBounds.intersect(dstBounds)) {
return false;
}
SkVector sigma = map_sigma(fSigma, ctx.ctm());
int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX;
int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY;
getBox3Params(sigma.x(), &kernelSizeX, &kernelSizeX3, &lowOffsetX, &highOffsetX);
getBox3Params(sigma.y(), &kernelSizeY, &kernelSizeY3, &lowOffsetY, &highOffsetY);
if (kernelSizeX < 0 || kernelSizeY < 0) {
return false;
}
if (kernelSizeX == 0 && kernelSizeY == 0) {
src.extractSubset(dst, srcBounds);
offset->fX = srcBounds.x();
offset->fY = srcBounds.y();
return true;
}
SkAutoLockPixels alp(src);
if (!src.getPixels()) {
return false;
}
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstBounds.width(), dstBounds.height()));
if (!device) {
return false;
}
*dst = device->accessBitmap(false);
SkAutoLockPixels alp_dst(*dst);
SkAutoTUnref<SkBaseDevice> tempDevice(proxy->createDevice(dst->width(), dst->height()));
if (!tempDevice) {
return false;
}
SkBitmap temp = tempDevice->accessBitmap(false);
SkAutoLockPixels alpTemp(temp);
offset->fX = dstBounds.fLeft;
offset->fY = dstBounds.fTop;
SkPMColor* t = temp.getAddr32(0, 0);
SkPMColor* d = dst->getAddr32(0, 0);
int w = dstBounds.width(), h = dstBounds.height();
const SkPMColor* s = src.getAddr32(srcBounds.x() - srcOffset.x(), srcBounds.y() - srcOffset.y());
srcBounds.offset(-dstBounds.x(), -dstBounds.y());
dstBounds.offset(-dstBounds.x(), -dstBounds.y());
SkIRect srcBoundsT = SkIRect::MakeLTRB(srcBounds.top(), srcBounds.left(), srcBounds.bottom(), srcBounds.right());
SkIRect dstBoundsT = SkIRect::MakeWH(dstBounds.height(), dstBounds.width());
int sw = src.rowBytesAsPixels();
/**
*
* In order to make memory accesses cache-friendly, we reorder the passes to
* use contiguous memory reads wherever possible.
*
* For example, the 6 passes of the X-and-Y blur case are rewritten as
* follows. Instead of 3 passes in X and 3 passes in Y, we perform
* 2 passes in X, 1 pass in X transposed to Y on write, 2 passes in X,
* then 1 pass in X transposed to Y on write.
*
* +----+ +----+ +----+ +---+ +---+ +---+ +----+
* + AB + ----> | AB | ----> | AB | -----> | A | ----> | A | ----> | A | -----> | AB |
* +----+ blurX +----+ blurX +----+ blurXY | B | blurX | B | blurX | B | blurXY +----+
* +---+ +---+ +---+
*
* In this way, two of the y-blurs become x-blurs applied to transposed
* images, and all memory reads are contiguous.
*/
if (kernelSizeX > 0 && kernelSizeY > 0) {
SkOpts::box_blur_xx(s, sw, srcBounds, t, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, w, dstBounds, d, kernelSizeX, highOffsetX, lowOffsetX, w, h);
SkOpts::box_blur_xy(d, w, dstBounds, t, kernelSizeX3, highOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(t, h, dstBoundsT, d, kernelSizeY, lowOffsetY, highOffsetY, h, w);
SkOpts::box_blur_xx(d, h, dstBoundsT, t, kernelSizeY, highOffsetY, lowOffsetY, h, w);
SkOpts::box_blur_xy(t, h, dstBoundsT, d, kernelSizeY3, highOffsetY, highOffsetY, h, w);
} else if (kernelSizeX > 0) {
SkOpts::box_blur_xx(s, sw, srcBounds, d, kernelSizeX, lowOffsetX, highOffsetX, w, h);
SkOpts::box_blur_xx(d, w, dstBounds, t, kernelSizeX, highOffsetX, lowOffsetX, w, h);
//.........这里部分代码省略.........
示例13: writePixels
void SkBitmapDevice::writePixels(const SkBitmap& bitmap,
int x, int y,
SkCanvas::Config8888 config8888) {
if (bitmap.isNull() || bitmap.getTexture()) {
return;
}
const SkBitmap* sprite = &bitmap;
// check whether we have to handle a config8888 that doesn't match SkPMColor
if (SkBitmap::kARGB_8888_Config == bitmap.config() &&
SkCanvas::kNative_Premul_Config8888 != config8888 &&
kPMColorAlias != config8888) {
// We're going to have to convert from a config8888 to the native config
// First we clip to the device bounds.
SkBitmap dstBmp = this->accessBitmap(true);
SkIRect spriteRect = SkIRect::MakeXYWH(x, y,
bitmap.width(), bitmap.height());
SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height());
if (!spriteRect.intersect(devRect)) {
return;
}
// write directly to the device if it has pixels and is SkPMColor
bool drawSprite;
if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) {
// we can write directly to the dst when doing the conversion
dstBmp.extractSubset(&dstBmp, spriteRect);
drawSprite = false;
} else {
// we convert to a temporary bitmap and draw that as a sprite
dstBmp.setConfig(SkBitmap::kARGB_8888_Config,
spriteRect.width(),
spriteRect.height());
if (!dstBmp.allocPixels()) {
return;
}
drawSprite = true;
}
// copy pixels to dstBmp and convert from config8888 to native config.
SkAutoLockPixels alp(bitmap);
uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x,
spriteRect.fTop - y);
SkCopyConfig8888ToBitmap(dstBmp,
srcPixels,
bitmap.rowBytes(),
config8888);
if (drawSprite) {
// we've clipped the sprite when we made a copy
x = spriteRect.fLeft;
y = spriteRect.fTop;
sprite = &dstBmp;
} else {
return;
}
}
SkPaint paint;
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
SkRasterClip clip(SkIRect::MakeWH(fBitmap.width(), fBitmap.height()));
SkDraw draw;
draw.fRC = &clip;
draw.fClip = &clip.bwRgn();
draw.fBitmap = &fBitmap; // canvas should have already called accessBitmap
draw.fMatrix = &SkMatrix::I();
this->drawSprite(draw, *sprite, x, y, paint);
}
示例14: drawBatch
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
GrDrawContext* drawContext,
const GrClip& clip,
GrDrawBatch* batch) {
// Setup clip
GrAppliedClip appliedClip;
SkRect bounds;
batch_bounds(&bounds, batch);
if (!clip.apply(fContext, drawContext, &bounds,
pipelineBuilder.isHWAntialias(), pipelineBuilder.hasUserStencilSettings(),
&appliedClip)) {
return;
}
// TODO: this is the only remaining usage of the AutoRestoreFragmentProcessorState - remove it
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
if (appliedClip.getClipCoverageFragmentProcessor()) {
arfps.set(&pipelineBuilder);
arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverageFragmentProcessor()));
}
GrPipeline::CreateArgs args;
args.fPipelineBuilder = &pipelineBuilder;
args.fDrawContext = drawContext;
args.fCaps = this->caps();
args.fScissor = &appliedClip.scissorState();
args.fHasStencilClip = appliedClip.hasStencilClip();
if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
if (!fResourceProvider->attachStencilAttachment(drawContext->accessRenderTarget())) {
SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
return;
}
}
batch->getPipelineOptimizations(&args.fOpts);
GrScissorState finalScissor;
if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) {
GrGLIRect viewport;
viewport.fLeft = 0;
viewport.fBottom = 0;
viewport.fWidth = drawContext->width();
viewport.fHeight = drawContext->height();
SkIRect ibounds;
ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft,
viewport.fWidth);
ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom,
viewport.fHeight);
ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft,
viewport.fWidth);
ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
viewport.fHeight);
if (appliedClip.scissorState().enabled()) {
const SkIRect& scissorRect = appliedClip.scissorState().rect();
if (!ibounds.intersect(scissorRect)) {
return;
}
}
finalScissor.set(ibounds);
args.fScissor = &finalScissor;
}
args.fOpts.fColorPOI.completeCalculations(
sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()),
pipelineBuilder.numColorFragmentProcessors());
args.fOpts.fCoveragePOI.completeCalculations(
sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()),
pipelineBuilder.numCoverageFragmentProcessors());
if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRenderTarget(),
clip, args.fOpts,
&args.fDstTexture, batch->bounds())) {
return;
}
if (!batch->installPipeline(args)) {
return;
}
#ifdef ENABLE_MDB
SkASSERT(fRenderTarget);
batch->pipeline()->addDependenciesTo(fRenderTarget);
#endif
SkRect clippedBounds;
SkAssertResult(intersect(&clippedBounds, bounds, appliedClip.deviceBounds()));
this->recordBatch(batch, clippedBounds);
}
示例15: drawResampledBitmap
// Draws the given bitmap to the given canvas. The subset of the source bitmap
// identified by src_rect is drawn to the given destination rect. The bitmap
// will be resampled to resample_width * resample_height (this is the size of
// the whole image, not the subset). See shouldResampleBitmap for more.
//
// This does a lot of computation to resample only the portion of the bitmap
// that will only be drawn. This is critical for performance since when we are
// scrolling, for example, we are only drawing a small strip of the image.
// Resampling the whole image every time is very slow, so this speeds up things
// dramatically.
static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeImageSkia& bitmap, const SkIRect& srcIRect, const SkRect& destRect)
{
// First get the subset we need. This is efficient and does not copy pixels.
SkBitmap subset;
bitmap.extractSubset(&subset, srcIRect);
SkRect srcRect;
srcRect.set(srcIRect);
// Whether we're doing a subset or using the full source image.
bool srcIsFull = srcIRect.fLeft == 0 && srcIRect.fTop == 0
&& srcIRect.width() == bitmap.width()
&& srcIRect.height() == bitmap.height();
// We will always draw in integer sizes, so round the destination rect.
SkIRect destRectRounded;
destRect.round(&destRectRounded);
SkIRect resizedImageRect = // Represents the size of the resized image.
{ 0, 0, destRectRounded.width(), destRectRounded.height() };
if (srcIsFull && bitmap.hasResizedBitmap(destRectRounded.width(), destRectRounded.height())) {
// Yay, this bitmap frame already has a resized version.
SkBitmap resampled = bitmap.resizedBitmap(destRectRounded.width(), destRectRounded.height());
canvas.drawBitmapRect(resampled, 0, destRect, &paint);
return;
}
// Compute the visible portion of our rect.
SkRect destBitmapSubsetSk;
ClipRectToCanvas(canvas, destRect, &destBitmapSubsetSk);
destBitmapSubsetSk.offset(-destRect.fLeft, -destRect.fTop);
// The matrix inverting, etc. could have introduced rounding error which
// causes the bounds to be outside of the resized bitmap. We round outward
// so we always lean toward it being larger rather than smaller than we
// need, and then clamp to the bitmap bounds so we don't get any invalid
// data.
SkIRect destBitmapSubsetSkI;
destBitmapSubsetSk.roundOut(&destBitmapSubsetSkI);
if (!destBitmapSubsetSkI.intersect(resizedImageRect))
return; // Resized image does not intersect.
if (srcIsFull && bitmap.shouldCacheResampling(
resizedImageRect.width(),
resizedImageRect.height(),
destBitmapSubsetSkI.width(),
destBitmapSubsetSkI.height())) {
// We're supposed to resize the entire image and cache it, even though
// we don't need all of it.
SkBitmap resampled = bitmap.resizedBitmap(destRectRounded.width(),
destRectRounded.height());
canvas.drawBitmapRect(resampled, 0, destRect, &paint);
} else {
// We should only resize the exposed part of the bitmap to do the
// minimal possible work.
// Resample the needed part of the image.
SkBitmap resampled = skia::ImageOperations::Resize(subset,
skia::ImageOperations::RESIZE_LANCZOS3,
destRectRounded.width(), destRectRounded.height(),
destBitmapSubsetSkI);
// Compute where the new bitmap should be drawn. Since our new bitmap
// may be smaller than the original, we have to shift it over by the
// same amount that we cut off the top and left.
destBitmapSubsetSkI.offset(destRect.fLeft, destRect.fTop);
SkRect offsetDestRect;
offsetDestRect.set(destBitmapSubsetSkI);
canvas.drawBitmapRect(resampled, 0, offsetDestRect, &paint);
}
}