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:
parent
98f4e5cea3
commit
8865d09cf8
@ -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)); )
|
||||
}
|
@ -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',
|
||||
|
@ -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',
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user