зеркало из https://github.com/mozilla/moz-skia.git
Minimize use of SkDraw's matrix in SkGpuDevice.
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6604068 git-svn-id: http://skia.googlecode.com/svn/trunk@5906 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
5dc26b9736
Коммит
3ab43d5c5b
|
@ -63,6 +63,13 @@ public:
|
|||
BoundsType* boundType,
|
||||
bool* isIntersectionOfRects = NULL) const;
|
||||
|
||||
/**
|
||||
* Takes an input rect in device space and conservatively clips it to the
|
||||
* clip-stack. If false is returned then the rect does not intersect the
|
||||
* clip and is unmodified.
|
||||
*/
|
||||
bool intersectRectWithClip(SkRect* devRect) const;
|
||||
|
||||
void clipDevRect(const SkIRect& ir, SkRegion::Op op) {
|
||||
SkRect r;
|
||||
r.set(ir);
|
||||
|
|
|
@ -481,6 +481,13 @@ struct SK_API SkRect {
|
|||
fBottom = y + height;
|
||||
}
|
||||
|
||||
void setWH(SkScalar width, SkScalar height) {
|
||||
fLeft = 0;
|
||||
fTop = 0;
|
||||
fRight = width;
|
||||
fBottom = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the largest representable rectangle
|
||||
*/
|
||||
|
|
|
@ -145,27 +145,34 @@ private:
|
|||
bool bindDeviceAsTexture(GrPaint* paint);
|
||||
|
||||
void prepareDraw(const SkDraw&); // sets the render target, clip, and matrix on GrContext.
|
||||
bool shouldTileBitmap(const SkBitmap& bitmap,
|
||||
const GrTextureParams& sampler,
|
||||
const SkRect* srcRectPtr) const;
|
||||
void internalDrawBitmap(const SkDraw&,
|
||||
const SkBitmap&,
|
||||
const SkRect&,
|
||||
const SkMatrix&,
|
||||
const GrTextureParams& params,
|
||||
GrPaint* grPaint);
|
||||
void drawTiledBitmap(const SkDraw& draw,
|
||||
const SkBitmap& bitmap,
|
||||
const SkRect& srcRect,
|
||||
const SkMatrix& m,
|
||||
const GrTextureParams& params,
|
||||
GrPaint* grPaint);
|
||||
|
||||
/**
|
||||
* Implementation for both drawBitmap and drawBitmapRect.
|
||||
*/
|
||||
void drawBitmapCommon(const SkDraw&,
|
||||
const SkBitmap& bitmap,
|
||||
const SkRect* srcRectPtr,
|
||||
const SkMatrix&,
|
||||
const SkPaint&);
|
||||
|
||||
/**
|
||||
* Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
|
||||
* matrix has already been set on GrContext
|
||||
*/
|
||||
bool shouldTileBitmap(const SkBitmap& bitmap,
|
||||
const GrTextureParams& sampler,
|
||||
const SkRect* srcRectPtr) const;
|
||||
void internalDrawBitmap(const SkBitmap&,
|
||||
const SkRect&,
|
||||
const SkMatrix&,
|
||||
const GrTextureParams& params,
|
||||
GrPaint* grPaint);
|
||||
void drawTiledBitmap(const SkBitmap& bitmap,
|
||||
const SkRect& srcRect,
|
||||
const SkMatrix& m,
|
||||
const GrTextureParams& params,
|
||||
GrPaint* grPaint);
|
||||
|
||||
/**
|
||||
* Returns non-initialized instance.
|
||||
*/
|
||||
|
|
|
@ -567,6 +567,25 @@ void SkClipStack::getBounds(SkRect* canvFiniteBound,
|
|||
}
|
||||
}
|
||||
|
||||
bool SkClipStack::intersectRectWithClip(SkRect* rect) const {
|
||||
SkASSERT(NULL != rect);
|
||||
|
||||
SkRect bounds;
|
||||
SkClipStack::BoundsType bt;
|
||||
this->getBounds(&bounds, &bt);
|
||||
if (bt == SkClipStack::kInsideOut_BoundsType) {
|
||||
if (bounds.contains(*rect)) {
|
||||
return false;
|
||||
} else {
|
||||
// If rect's x values are both within bound's x range we
|
||||
// could clip here. Same for y. But we don't bother to check.
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return rect->intersect(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) {
|
||||
|
||||
int32_t genID = GetNextGenID();
|
||||
|
|
|
@ -686,7 +686,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
|
||||
const SkPaint& paint) {
|
||||
const SkPaint& paint) {
|
||||
CHECK_FOR_NODRAW_ANNOTATION(paint);
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
|
@ -704,7 +704,7 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
|
|||
usePath = true;
|
||||
}
|
||||
// until we aa rotated rects...
|
||||
if (!usePath && paint.isAntiAlias() && !draw.fMatrix->rectStaysRect()) {
|
||||
if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
|
||||
usePath = true;
|
||||
}
|
||||
// small miter limit means right angles show bevel...
|
||||
|
@ -773,10 +773,9 @@ inline bool shouldDrawBlurWithCPU(const SkRect& rect, SkScalar radius) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
||||
SkMaskFilter* filter, const SkMatrix& matrix,
|
||||
const SkRegion& clip, SkBounder* bounder,
|
||||
GrPaint* grp, GrPathFill pathFillType) {
|
||||
bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath,
|
||||
SkMaskFilter* filter, const SkRegion& clip,
|
||||
SkBounder* bounder, GrPaint* grp, GrPathFill pathFillType) {
|
||||
#ifdef SK_DISABLE_GPU_BLUR
|
||||
return false;
|
||||
#endif
|
||||
|
@ -786,13 +785,13 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
return false;
|
||||
}
|
||||
SkScalar radius = info.fIgnoreTransform ? info.fRadius
|
||||
: matrix.mapRadius(info.fRadius);
|
||||
: context->getMatrix().mapRadius(info.fRadius);
|
||||
radius = SkMinScalar(radius, MAX_BLUR_RADIUS);
|
||||
if (radius <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SkRect srcRect = path.getBounds();
|
||||
SkRect srcRect = devPath.getBounds();
|
||||
if (shouldDrawBlurWithCPU(srcRect, radius)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -838,6 +837,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
|
||||
SkAutoTUnref<GrTexture> blurTexture;
|
||||
|
||||
GrMatrix origMatrix = context->getMatrix();
|
||||
|
||||
// We pass kPreserve here. We will replace the current matrix below.
|
||||
GrContext::AutoMatrix avm(context, GrContext::AutoMatrix::kPreserve_InitialMatrix);
|
||||
|
||||
|
@ -846,8 +847,12 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
GrContext::AutoClip ac(context, srcRect);
|
||||
|
||||
context->clear(NULL, 0);
|
||||
GrPaint tempPaint;
|
||||
|
||||
// Draw hard shadow to pathTexture with path top-left at origin 0,0.
|
||||
GrMatrix translate;
|
||||
translate.setTranslate(offset.fX, offset.fY);
|
||||
|
||||
GrPaint tempPaint;
|
||||
if (grp->isAntiAlias()) {
|
||||
tempPaint.setAntiAlias(true);
|
||||
// AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
|
||||
|
@ -858,11 +863,8 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
// use a zero dst coeff when dual source blending isn't available.
|
||||
tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
|
||||
}
|
||||
// Draw hard shadow to pathTexture with path top-left at origin 0,0.
|
||||
GrMatrix translate;
|
||||
translate.setTranslate(offset.fX, offset.fY);
|
||||
context->setMatrix(translate);
|
||||
context->drawPath(tempPaint, path, pathFillType);
|
||||
context->drawPath(tempPaint, devPath, pathFillType);
|
||||
|
||||
// switch to device coord drawing when going back to the main RT.
|
||||
context->setIdentityMatrix();
|
||||
|
@ -898,7 +900,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
}
|
||||
}
|
||||
|
||||
if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
|
||||
if (!grp->preConcatSamplerMatricesWithInverse(origMatrix)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -916,20 +918,18 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool drawWithMaskFilter(GrContext* context, const SkPath& path,
|
||||
SkMaskFilter* filter, const SkMatrix& matrix,
|
||||
const SkRegion& clip, SkBounder* bounder,
|
||||
bool drawWithMaskFilter(GrContext* context, const SkPath& devPath,
|
||||
SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder,
|
||||
GrPaint* grp, SkPaint::Style style) {
|
||||
SkMask srcM, dstM;
|
||||
|
||||
if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
|
||||
SkMask::kComputeBoundsAndRenderImage_CreateMode,
|
||||
style)) {
|
||||
if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM,
|
||||
SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
|
||||
return false;
|
||||
}
|
||||
SkAutoMaskFreeImage autoSrc(srcM.fImage);
|
||||
|
||||
if (!filter->filterMask(&dstM, srcM, matrix, NULL)) {
|
||||
if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) {
|
||||
return false;
|
||||
}
|
||||
// this will free-up dstM when we're done (allocated in filterMask())
|
||||
|
@ -945,12 +945,12 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& path,
|
|||
// we now have a device-aligned 8bit mask in dstM, ready to be drawn using
|
||||
// the current clip (and identity matrix) and grpaint settings
|
||||
|
||||
GrContext::AutoMatrix avm(context, GrMatrix::I());
|
||||
|
||||
if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
|
||||
if (!grp->preConcatSamplerMatricesWithInverse(context->getMatrix())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GrContext::AutoMatrix avm(context, GrMatrix::I());
|
||||
|
||||
GrTextureDesc desc;
|
||||
desc.fWidth = dstM.fBounds.width();
|
||||
desc.fHeight = dstM.fBounds.height();
|
||||
|
@ -1010,7 +1010,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
|||
// can we cheat, and threat a thin stroke as a hairline w/ coverage
|
||||
// if we can, we draw lots faster (raster device does this same test)
|
||||
SkScalar hairlineCoverage;
|
||||
if (SkDrawTreatAsHairline(paint, *draw.fMatrix, &hairlineCoverage)) {
|
||||
if (SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage)) {
|
||||
doFill = false;
|
||||
grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
|
||||
}
|
||||
|
@ -1050,17 +1050,15 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
|
|||
SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
|
||||
|
||||
// transform the path into device space
|
||||
pathPtr->transform(*draw.fMatrix, devPathPtr);
|
||||
pathPtr->transform(fContext->getMatrix(), devPathPtr);
|
||||
GrPathFill pathFillType = doFill ?
|
||||
skToGrFillType(devPathPtr->getFillType()) : kHairLine_GrPathFill;
|
||||
if (!drawWithGPUMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
|
||||
*draw.fMatrix, *draw.fClip, draw.fBounder,
|
||||
&grPaint, pathFillType)) {
|
||||
*draw.fClip, draw.fBounder, &grPaint, pathFillType)) {
|
||||
SkPaint::Style style = doFill ? SkPaint::kFill_Style :
|
||||
SkPaint::kStroke_Style;
|
||||
drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
|
||||
*draw.fMatrix, *draw.fClip, draw.fBounder,
|
||||
&grPaint, style);
|
||||
*draw.fClip, draw.fBounder, &grPaint, style);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -1235,11 +1233,11 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
|
|||
paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
|
||||
SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
|
||||
|
||||
// Transform 'newM' needs to be concatenated to the draw matrix,
|
||||
// Transform 'newM' needs to be concatenated to the current matrix,
|
||||
// rather than transforming the primitive directly, so that 'newM' will
|
||||
// also affect the behavior of the mask filter.
|
||||
SkMatrix drawMatrix;
|
||||
drawMatrix.setConcat(*draw.fMatrix, newM);
|
||||
drawMatrix.setConcat(fContext->getMatrix(), newM);
|
||||
SkDraw transformedDraw(draw);
|
||||
transformedDraw.fMatrix = &drawMatrix;
|
||||
|
||||
|
@ -1258,16 +1256,15 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
|
|||
|
||||
if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
|
||||
// take the simple case
|
||||
this->internalDrawBitmap(draw, bitmap, srcRect, m, params, &grPaint);
|
||||
this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint);
|
||||
} else {
|
||||
this->drawTiledBitmap(draw, bitmap, srcRect, m, params, &grPaint);
|
||||
this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint);
|
||||
}
|
||||
}
|
||||
|
||||
// Break 'bitmap' into several tiles to draw it since it has already
|
||||
// been determined to be too large to fit in VRAM
|
||||
void SkGpuDevice::drawTiledBitmap(const SkDraw& draw,
|
||||
const SkBitmap& bitmap,
|
||||
void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
|
||||
const SkRect& srcRect,
|
||||
const SkMatrix& m,
|
||||
const GrTextureParams& params,
|
||||
|
@ -1279,9 +1276,13 @@ void SkGpuDevice::drawTiledBitmap(const SkDraw& draw,
|
|||
// compute clip bounds in local coordinates
|
||||
SkRect clipRect;
|
||||
{
|
||||
clipRect.set(draw.fClip->getBounds());
|
||||
const GrRenderTarget* rt = fContext->getRenderTarget();
|
||||
clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height()));
|
||||
if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
|
||||
return;
|
||||
}
|
||||
SkMatrix matrix, inverse;
|
||||
matrix.setConcat(*draw.fMatrix, m);
|
||||
matrix.setConcat(fContext->getMatrix(), m);
|
||||
if (!matrix.invert(&inverse)) {
|
||||
return;
|
||||
}
|
||||
|
@ -1316,7 +1317,7 @@ void SkGpuDevice::drawTiledBitmap(const SkDraw& draw,
|
|||
tmpM.preTranslate(SkIntToScalar(iTileR.fLeft),
|
||||
SkIntToScalar(iTileR.fTop));
|
||||
|
||||
this->internalDrawBitmap(draw, tmpB, tileR, tmpM, params, grPaint);
|
||||
this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1372,8 +1373,7 @@ bool mayColorBleed(const SkRect& srcRect, const SkRect& transformedRect,
|
|||
* internalDrawBitmap assumes that the specified bitmap will fit in a texture
|
||||
* and that non-texture portion of the GrPaint has already been setup.
|
||||
*/
|
||||
void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
|
||||
const SkBitmap& bitmap,
|
||||
void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
|
||||
const SkRect& srcRect,
|
||||
const SkMatrix& m,
|
||||
const GrTextureParams& params,
|
||||
|
@ -1411,11 +1411,11 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
|
|||
// Need texture domain if drawing a sub rect.
|
||||
needsTextureDomain = srcRect.width() < bitmap.width() ||
|
||||
srcRect.height() < bitmap.height();
|
||||
if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) {
|
||||
if (m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) {
|
||||
// sampling is axis-aligned
|
||||
GrRect transformedRect;
|
||||
SkMatrix srcToDeviceMatrix(m);
|
||||
srcToDeviceMatrix.postConcat(*draw.fMatrix);
|
||||
srcToDeviceMatrix.postConcat(fContext->getMatrix());
|
||||
srcToDeviceMatrix.mapRect(&transformedRect, srcRect);
|
||||
|
||||
if (hasAlignedSamples(srcRect, transformedRect)) {
|
||||
|
@ -1802,7 +1802,7 @@ void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
|
|||
const SkPaint& paint) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (draw.fMatrix->hasPerspective()) {
|
||||
if (fContext->getMatrix().hasPerspective()) {
|
||||
// this guy will just call our drawPath()
|
||||
draw.drawText((const char*)text, byteLength, x, y, paint);
|
||||
} else {
|
||||
|
@ -1829,7 +1829,7 @@ void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text,
|
|||
const SkPaint& paint) {
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
if (draw.fMatrix->hasPerspective()) {
|
||||
if (fContext->getMatrix().hasPerspective()) {
|
||||
// this guy will just call our drawPath()
|
||||
draw.drawPosText((const char*)text, byteLength, pos, constY,
|
||||
scalarsPerPos, paint);
|
||||
|
|
Загрузка…
Ссылка в новой задаче