Revert of Initial picture shader implementation (https://codereview.chromium.org/221923007/)

Reason for revert:
breaking the buildbots. Subsequent CL only addressed CompareGMs but GenerateGMs are also failing.

Original issue's description:
> Initial picture shader implementation
>
> This CL adds an SkPictureShader class to support SkPicture-based
> patterns.
>
> The implementation renders the picture into an SkBitmap tile and then
> delegates to SkBitmapProcShader for the actual operation.
>
> R=reed@google.com,robertphillips@google.com,bsalomon@google.com
>
> Committed: http://code.google.com/p/skia/source/detail?r=14085

R=bsalomon@google.com, reed@google.com, robertphillips@google.com, fmalita@chromium.org
TBR=bsalomon@google.com, fmalita@chromium.org, reed@google.com, robertphillips@google.com
NOTREECHECKS=true
NOTRY=true

Author: bensong@google.com

Review URL: https://codereview.chromium.org/227553010

git-svn-id: http://skia.googlecode.com/svn/trunk@14087 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
commit-bot@chromium.org 2014-04-07 23:45:31 +00:00
parent 98f4e5cea3
commit 8865d09cf8
7 changed files with 0 additions and 430 deletions

View File

@ -1,165 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm.h"
#include "SkBitmap.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkShader.h"
namespace skiagm {
static struct {
SkShader::TileMode tmx;
SkShader::TileMode tmy;
} kTileConfigs[] = {
{ SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode },
{ SkShader::kRepeat_TileMode, SkShader::kClamp_TileMode },
{ SkShader::kMirror_TileMode, SkShader::kRepeat_TileMode },
};
class PictureShaderGM : public GM {
public:
PictureShaderGM(SkScalar tileSize, SkScalar sceneSize)
: fTileSize(tileSize)
, fSceneSize(sceneSize) {
// Build the picture.
SkAutoTUnref<SkPicture> p(SkNEW(SkPicture));
SkCanvas* pictureCanvas = p->beginRecording(SkScalarRoundToInt(tileSize),
SkScalarRoundToInt(tileSize));
this->drawTile(pictureCanvas);
p->endRecording();
// Build a reference bitmap.
SkBitmap bm;
bm.allocN32Pixels(SkScalarRoundToInt(tileSize), SkScalarRoundToInt(tileSize));
bm.eraseColor(SK_ColorTRANSPARENT);
SkCanvas bitmapCanvas(bm);
this->drawTile(&bitmapCanvas);
for (unsigned i = 0; i < SK_ARRAY_COUNT(kTileConfigs); ++i) {
fPictureShaders[i].reset(SkShader::CreatePictureShader(p,
kTileConfigs[i].tmx,
kTileConfigs[i].tmy));
fBitmapShaders[i].reset(SkShader::CreateBitmapShader(bm,
kTileConfigs[i].tmx,
kTileConfigs[i].tmy));
}
}
protected:
virtual SkString onShortName() SK_OVERRIDE {
return SkString("pictureshader");
}
virtual SkISize onISize() SK_OVERRIDE {
return SkISize::Make(1400, 1250);
}
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
this->drawSceneColumn(canvas, SkPoint::Make(0, 0), 1, 1, 0);
this->drawSceneColumn(canvas, SkPoint::Make(0, fSceneSize * 6.4f), 1, 2, 0);
this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, 0), 1, 1, 1);
this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 2.4f, fSceneSize * 6.4f), 1, 1, 2);
this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 4.8f, 0), 2, 1, 0);
this->drawSceneColumn(canvas, SkPoint::Make(fSceneSize * 9.6f, 0), 2, 2, 0);
}
private:
void drawSceneColumn(SkCanvas* canvas, const SkPoint& pos, SkScalar scale, SkScalar localScale,
unsigned tileMode) {
SkMatrix ctm, localMatrix;
ctm.setTranslate(pos.x(), pos.y());
ctm.preScale(scale, scale);
localMatrix.setScale(localScale, localScale);
this->drawScene(canvas, ctm, localMatrix, tileMode);
ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 1.2f * scale);
ctm.preScale(scale, scale);
localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
localMatrix.preScale(localScale, localScale);
this->drawScene(canvas, ctm, localMatrix, tileMode);
ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 2.4f * scale);
ctm.preScale(scale, scale);
localMatrix.setRotate(45);
localMatrix.preScale(localScale, localScale);
this->drawScene(canvas, ctm, localMatrix, tileMode);
ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 3.6f * scale);
ctm.preScale(scale, scale);
localMatrix.setSkew(1, 0);
localMatrix.preScale(localScale, localScale);
this->drawScene(canvas, ctm, localMatrix, tileMode);
ctm.setTranslate(pos.x(), pos.y() + fSceneSize * 4.8f * scale);
ctm.preScale(scale, scale);
localMatrix.setTranslate(fTileSize / 4, fTileSize / 4);
localMatrix.preRotate(45);
localMatrix.preScale(localScale, localScale);
this->drawScene(canvas, ctm, localMatrix, tileMode);
}
void drawTile(SkCanvas* canvas) {
SkPaint paint;
paint.setColor(SK_ColorGREEN);
paint.setStyle(SkPaint::kFill_Style);
paint.setAntiAlias(true);
canvas->drawCircle(fTileSize / 4, fTileSize / 4, fTileSize / 4, paint);
canvas->drawRect(SkRect::MakeXYWH(fTileSize / 2, fTileSize / 2,
fTileSize / 2, fTileSize / 2), paint);
paint.setColor(SK_ColorRED);
canvas->drawLine(fTileSize / 2, fTileSize * 1 / 3,
fTileSize / 2, fTileSize * 2 / 3, paint);
canvas->drawLine(fTileSize * 1 / 3, fTileSize / 2,
fTileSize * 2 / 3, fTileSize / 2, paint);
}
void drawScene(SkCanvas* canvas, const SkMatrix& matrix, const SkMatrix& localMatrix,
unsigned tileMode) {
SkASSERT(tileMode < SK_ARRAY_COUNT(kTileConfigs));
SkPaint paint;
paint.setStyle(SkPaint::kFill_Style);
paint.setColor(SK_ColorLTGRAY);
canvas->save();
canvas->concat(matrix);
canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
canvas->drawRect(SkRect::MakeXYWH(fSceneSize * 1.1f, 0, fSceneSize, fSceneSize), paint);
fPictureShaders[tileMode]->setLocalMatrix(localMatrix);
paint.setShader(fPictureShaders[tileMode].get());
canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
canvas->translate(fSceneSize * 1.1f, 0);
fBitmapShaders[tileMode]->setLocalMatrix(localMatrix);
paint.setShader(fBitmapShaders[tileMode].get());
canvas->drawRect(SkRect::MakeWH(fSceneSize, fSceneSize), paint);
canvas->restore();
}
SkScalar fTileSize;
SkScalar fSceneSize;
SkAutoTUnref<SkShader> fPictureShaders[SK_ARRAY_COUNT(kTileConfigs)];
SkAutoTUnref<SkShader> fBitmapShaders[SK_ARRAY_COUNT(kTileConfigs)];
typedef GM INHERITED;
};
DEF_GM( return SkNEW_ARGS(PictureShaderGM, (50, 100)); )
}

View File

@ -135,8 +135,6 @@
'<(skia_src_path)/core/SkPicturePlayback.h',
'<(skia_src_path)/core/SkPictureRecord.cpp',
'<(skia_src_path)/core/SkPictureRecord.h',
'<(skia_src_path)/core/SkPictureShader.cpp',
'<(skia_src_path)/core/SkPictureShader.h',
'<(skia_src_path)/core/SkPictureStateTree.cpp',
'<(skia_src_path)/core/SkPictureStateTree.h',
'<(skia_src_path)/core/SkPixelRef.cpp',

View File

@ -127,7 +127,6 @@
'../gm/peekpixels.cpp',
'../gm/perlinnoise.cpp',
'../gm/pictureimagefilter.cpp',
'../gm/pictureshader.cpp',
'../gm/points.cpp',
'../gm/poly2poly.cpp',
'../gm/polygons.cpp',

View File

@ -16,7 +16,6 @@
#include "SkPaint.h"
class SkPath;
class SkPicture;
class GrContext;
class GrEffectRef;
@ -346,16 +345,6 @@ public:
static SkShader* CreateBitmapShader(const SkBitmap& src,
TileMode tmx, TileMode tmy);
/** Call this to create a new shader that will draw with the specified picture.
*
* @param src The picture to use inside the shader (if not NULL, its ref count
* is incremented).
* @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
* @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
* @return Returns a new shader object. Note: this function never returns null.
*/
static SkShader* CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy);
SK_TO_STRING_VIRT()
SK_DEFINE_FLATTENABLE_TYPE(SkShader)

View File

@ -1,185 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkPictureShader.h"
#include "SkBitmap.h"
#include "SkBitmapProcShader.h"
#include "SkCanvas.h"
#include "SkMatrixUtils.h"
#include "SkPicture.h"
#include "SkReadBuffer.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
#endif
SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy)
: fPicture(picture)
, fTmx(tmx)
, fTmy(tmy) {
SkSafeRef(fPicture);
}
SkPictureShader::SkPictureShader(SkReadBuffer& buffer)
: INHERITED(buffer) {
fTmx = static_cast<SkShader::TileMode>(buffer.read32());
fTmy = static_cast<SkShader::TileMode>(buffer.read32());
if (buffer.readBool()) {
fPicture = SkPicture::CreateFromBuffer(buffer);
} else {
fPicture = NULL;
}
}
SkPictureShader::~SkPictureShader() {
SkSafeUnref(fPicture);
}
SkPictureShader* SkPictureShader::Create(SkPicture* picture, TileMode tmx, TileMode tmy) {
return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy));
}
void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
buffer.write32(fTmx);
buffer.write32(fTmy);
buffer.writeBool(NULL != fPicture);
if (fPicture) {
fPicture->flatten(buffer);
}
}
bool SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const {
if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) {
return false;
}
SkMatrix m;
if (this->hasLocalMatrix()) {
m.setConcat(matrix, this->getLocalMatrix());
} else {
m = matrix;
}
// Use a rotation-invariant scale
SkPoint scale;
if (!SkDecomposeUpper2x2(m, NULL, &scale, NULL)) {
// Decomposition failed, use an approximation.
scale.set(SkScalarSqrt(m.getScaleX() * m.getScaleX() + m.getSkewX() * m.getSkewX()),
SkScalarSqrt(m.getScaleY() * m.getScaleY() + m.getSkewY() * m.getSkewY()));
}
SkSize scaledSize = SkSize::Make(scale.x() * fPicture->width(), scale.y() * fPicture->height());
SkISize tileSize = scaledSize.toRound();
if (tileSize.isEmpty()) {
return false;
}
// The actual scale, compensating for rounding.
SkSize tileScale = SkSize::Make(SkIntToScalar(tileSize.width()) / fPicture->width(),
SkIntToScalar(tileSize.height()) / fPicture->height());
if (!fCachedShader || tileScale != fCachedTileScale) {
SkBitmap bm;
if (!bm.allocN32Pixels(tileSize.width(), tileSize.height())) {
return false;
}
bm.eraseColor(SK_ColorTRANSPARENT);
SkCanvas canvas(bm);
canvas.scale(tileScale.width(), tileScale.height());
canvas.drawPicture(*fPicture);
fCachedShader.reset(CreateBitmapShader(bm, fTmx, fTmy));
fCachedTileScale = tileScale;
}
SkMatrix shaderMatrix = this->getLocalMatrix();
shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
fCachedShader->setLocalMatrix(shaderMatrix);
return true;
}
bool SkPictureShader::setContext(const SkBitmap& device,
const SkPaint& paint,
const SkMatrix& matrix) {
if (!this->buildBitmapShader(matrix)) {
return false;
}
if (!this->INHERITED::setContext(device, paint, matrix)) {
return false;
}
SkASSERT(fCachedShader);
if (!fCachedShader->setContext(device, paint, matrix)) {
this->INHERITED::endContext();
return false;
}
return true;
}
void SkPictureShader::endContext() {
SkASSERT(fCachedShader);
fCachedShader->endContext();
this->INHERITED::endContext();
}
uint32_t SkPictureShader::getFlags() {
if (NULL != fCachedShader) {
return fCachedShader->getFlags();
}
return 0;
}
SkShader::ShadeProc SkPictureShader::asAShadeProc(void** ctx) {
if (fCachedShader) {
return fCachedShader->asAShadeProc(ctx);
}
return NULL;
}
void SkPictureShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
SkASSERT(fCachedShader);
fCachedShader->shadeSpan(x, y, dstC, count);
}
void SkPictureShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) {
SkASSERT(fCachedShader);
fCachedShader->shadeSpan16(x, y, dstC, count);
}
#ifndef SK_IGNORE_TO_STRING
void SkPictureShader::toString(SkString* str) const {
static const char* gTileModeName[SkShader::kTileModeCount] = {
"clamp", "repeat", "mirror"
};
str->appendf("PictureShader: [%d:%d] ",
fPicture ? fPicture->width() : 0,
fPicture ? fPicture->height() : 0);
str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
this->INHERITED::toString(str);
}
#endif
#if SK_SUPPORT_GPU
GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint) const {
if (!this->buildBitmapShader(context->getMatrix())) {
return NULL;
}
SkASSERT(fCachedShader);
return fCachedShader->asNewEffect(context, paint);
}
#endif

View File

@ -1,60 +0,0 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPictureShader_DEFINED
#define SkPictureShader_DEFINED
#include "SkShader.h"
class SkBitmap;
class SkPicture;
/*
* An SkPictureShader can be used to draw SkPicture-based patterns.
*
* The SkPicture is first rendered into a tile, which is then used to shade the area according
* to specified tiling rules.
*/
class SkPictureShader : public SkShader {
public:
static SkPictureShader* Create(SkPicture*, TileMode, TileMode);
virtual ~SkPictureShader();
virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&) SK_OVERRIDE;
virtual void endContext() SK_OVERRIDE;
virtual uint32_t getFlags() SK_OVERRIDE;
virtual ShadeProc asAShadeProc(void** ctx) SK_OVERRIDE;
virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader)
#if SK_SUPPORT_GPU
GrEffectRef* asNewEffect(GrContext*, const SkPaint&) const SK_OVERRIDE;
#endif
protected:
SkPictureShader(SkReadBuffer&);
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
SkPictureShader(SkPicture*, TileMode, TileMode);
bool buildBitmapShader(const SkMatrix&) const;
SkPicture* fPicture;
TileMode fTmx, fTmy;
mutable SkAutoTUnref<SkShader> fCachedShader;
mutable SkSize fCachedTileScale;
typedef SkShader INHERITED;
};
#endif // SkPictureShader_DEFINED

View File

@ -9,8 +9,6 @@
#include "SkReadBuffer.h"
#include "SkMallocPixelRef.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkPictureShader.h"
#include "SkScalar.h"
#include "SkShader.h"
#include "SkWriteBuffer.h"
@ -181,10 +179,6 @@ SkShader* SkShader::CreateBitmapShader(const SkBitmap& src,
return ::CreateBitmapShader(src, tmx, tmy, NULL);
}
SkShader* SkShader::CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy) {
return SkPictureShader::Create(src, tmx, tmy);
}
#ifndef SK_IGNORE_TO_STRING
void SkShader::toString(SkString* str) const {
if (this->hasLocalMatrix()) {