add SkCanvas::drawAtlas
BUG=skia: Review URL: https://codereview.chromium.org/1181913003
This commit is contained in:
parent
52d4deb128
commit
71c3c760a8
103
gm/drawatlas.cpp
Normal file
103
gm/drawatlas.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2015 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 "SkCanvas.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
class DrawAtlasGM : public skiagm::GM {
|
||||
static SkImage* MakeAtlas(SkCanvas* caller, const SkRect& target) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
|
||||
SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
|
||||
if (NULL == surface) {
|
||||
surface.reset(SkSurface::NewRaster(info));
|
||||
}
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
// draw red everywhere, but we don't expect to see it in the draw, testing the notion
|
||||
// that drawAtlas draws a subset-region of the atlas.
|
||||
canvas->clear(SK_ColorRED);
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kClear_Mode);
|
||||
SkRect r(target);
|
||||
r.inset(-1, -1);
|
||||
// zero out a place (with a 1-pixel border) to land our drawing.
|
||||
canvas->drawRect(r, paint);
|
||||
paint.setXfermode(NULL);
|
||||
paint.setColor(SK_ColorBLUE);
|
||||
paint.setAntiAlias(true);
|
||||
canvas->drawOval(target, paint);
|
||||
return surface->newImageSnapshot();
|
||||
}
|
||||
|
||||
SkAutoTUnref<SkImage> fAtlas;
|
||||
|
||||
public:
|
||||
DrawAtlasGM() {}
|
||||
|
||||
protected:
|
||||
|
||||
SkString onShortName() override {
|
||||
return SkString("draw-atlas");
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(640, 480);
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
const SkRect target = { 50, 50, 80, 90 };
|
||||
if (NULL == fAtlas) {
|
||||
fAtlas.reset(MakeAtlas(canvas, target));
|
||||
}
|
||||
|
||||
const struct {
|
||||
SkScalar fScale;
|
||||
SkScalar fDegrees;
|
||||
SkScalar fTx;
|
||||
SkScalar fTy;
|
||||
|
||||
void apply(SkRSXform* xform) const {
|
||||
const SkScalar rad = SkDegreesToRadians(fDegrees);
|
||||
xform->fSCos = fScale * SkScalarCos(rad);
|
||||
xform->fSSin = fScale * SkScalarSin(rad);
|
||||
xform->fTx = fTx;
|
||||
xform->fTy = fTy;
|
||||
}
|
||||
} rec[] = {
|
||||
{ 1, 0, 10, 10 }, // just translate
|
||||
{ 2, 0, 110, 10 }, // scale + translate
|
||||
{ 1, 30, 210, 10 }, // rotate + translate
|
||||
{ 2, -30, 310, 30 }, // scale + rotate + translate
|
||||
};
|
||||
|
||||
const int N = SK_ARRAY_COUNT(rec);
|
||||
SkRSXform xform[N];
|
||||
SkRect tex[N];
|
||||
SkColor colors[N];
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
rec[i].apply(&xform[i]);
|
||||
tex[i] = target;
|
||||
colors[i] = 0x80FF0000 + (i * 40 * 256);
|
||||
}
|
||||
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
canvas->drawAtlas(fAtlas, xform, tex, N, NULL, &paint);
|
||||
canvas->translate(0, 100);
|
||||
canvas->drawAtlas(fAtlas, xform, tex, colors, N, SkXfermode::kSrcIn_Mode, NULL, &paint);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
DEF_GM( return new DrawAtlasGM; )
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "gm.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkBlurImageFilter.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
static void make_bm(SkBitmap* bm) {
|
||||
bm->allocN32Pixels(100, 100);
|
||||
@ -93,7 +95,5 @@ protected:
|
||||
private:
|
||||
typedef GM INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_GM( return new SpriteBitmapGM; )
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
'../samplecode/SampleAnimBlur.cpp',
|
||||
'../samplecode/SampleApp.cpp',
|
||||
'../samplecode/SampleArc.cpp',
|
||||
'../samplecode/SampleAtlas.cpp',
|
||||
'../samplecode/SampleBigBlur.cpp',
|
||||
'../samplecode/SampleBigGradient.cpp',
|
||||
'../samplecode/SampleBitmapRect.cpp',
|
||||
|
@ -28,6 +28,7 @@ class SkImage;
|
||||
class SkMetaData;
|
||||
class SkPicture;
|
||||
class SkRRect;
|
||||
struct SkRSXform;
|
||||
class SkSurface;
|
||||
class SkSurface_Base;
|
||||
class SkTextBlob;
|
||||
@ -1023,6 +1024,32 @@ public:
|
||||
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
||||
|
||||
/**
|
||||
* Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the
|
||||
* coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle
|
||||
* into a quad.
|
||||
*
|
||||
* xform maps [0, 0, tex.width, tex.height] -> quad
|
||||
*
|
||||
* The color array is optional. When specified, each color modulates the pixels in its
|
||||
* corresponding quad (via the specified SkXfermode::Mode).
|
||||
*
|
||||
* The cullRect is optional. When specified, it must be a conservative bounds of all of the
|
||||
* resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not
|
||||
* intersect the current clip.
|
||||
*
|
||||
* The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter
|
||||
* and xfermode are used to affect each of the quads.
|
||||
*/
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode, const SkRect* cullRect,
|
||||
const SkPaint* paint);
|
||||
|
||||
void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count,
|
||||
const SkRect* cullRect, const SkPaint* paint) {
|
||||
this->drawAtlas(atlas, xform, tex, NULL, count, SkXfermode::kDst_Mode, cullRect, paint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the contents of this drawable into the canvas. If the canvas is async
|
||||
* (e.g. it is recording into a picture) then the drawable will be referenced instead,
|
||||
@ -1197,6 +1224,9 @@ protected:
|
||||
virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
|
||||
const SkPoint texs[], const SkColor colors[], SkXfermode*,
|
||||
const uint16_t indices[], int indexCount, const SkPaint&);
|
||||
|
||||
virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*);
|
||||
virtual void onDrawPath(const SkPath&, const SkPaint&);
|
||||
virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
|
||||
virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*);
|
||||
|
@ -245,6 +245,11 @@ protected:
|
||||
// default implementation calls drawVertices
|
||||
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
||||
|
||||
// default implementation calls drawPath
|
||||
virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkXfermode::Mode, const SkPaint&);
|
||||
|
||||
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||
onCreateDevice on this device with kNeverTile_TileExpectation.
|
||||
*/
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "SkRect.h"
|
||||
|
||||
struct SkRSXform;
|
||||
class SkString;
|
||||
|
||||
/** \class SkMatrix
|
||||
@ -244,6 +245,9 @@ public:
|
||||
/** Set the matrix to rotate by the specified sine and cosine values.
|
||||
*/
|
||||
void setSinCos(SkScalar sinValue, SkScalar cosValue);
|
||||
|
||||
SkMatrix& setRSXform(const SkRSXform&);
|
||||
|
||||
/** Set the matrix to skew by sx and sy, with a pivot point at (px, py).
|
||||
The pivot point is the coordinate that should remain unchanged by the
|
||||
specified transformation.
|
||||
|
49
include/core/SkRSXform.h
Normal file
49
include/core/SkRSXform.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef SkRSXform_DEFINED
|
||||
#define SkRSXform_DEFINED
|
||||
|
||||
#include "SkScalar.h"
|
||||
|
||||
/**
|
||||
* A compressed form of a rotation+scale matrix.
|
||||
*
|
||||
* [ fSCos -fSSin fTx ]
|
||||
* [ fSSin fSCos fTy ]
|
||||
* [ 0 0 1 ]
|
||||
*/
|
||||
struct SkRSXform {
|
||||
SkScalar fSCos;
|
||||
SkScalar fSSin;
|
||||
SkScalar fTx;
|
||||
SkScalar fTy;
|
||||
|
||||
bool rectStaysRect() const {
|
||||
return 0 == fSCos || 0 == fSSin;
|
||||
}
|
||||
|
||||
void setIdentity() {
|
||||
fSCos = 1;
|
||||
fSSin = fTx = fTy = 0;
|
||||
}
|
||||
|
||||
void set(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty) {
|
||||
fSCos = scos;
|
||||
fSSin = ssin;
|
||||
fTx = tx;
|
||||
fTy = ty;
|
||||
}
|
||||
|
||||
void toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const;
|
||||
void toQuad(const SkSize& size, SkPoint quad[4]) const {
|
||||
this->toQuad(size.width(), size.height(), quad);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -186,6 +186,8 @@ protected:
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint&) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int count,
|
||||
SkXfermode::Mode, const SkRect* cullRect, const SkPaint*) override;
|
||||
|
||||
void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||
|
234
samplecode/SampleAtlas.cpp
Normal file
234
samplecode/SampleAtlas.cpp
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SampleCode.h"
|
||||
#include "SkAnimTimer.h"
|
||||
#include "SkView.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkDrawable.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkSurface.h"
|
||||
|
||||
static SkImage* make_atlas(int atlasSize, int cellSize) {
|
||||
SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
|
||||
SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
|
||||
SkCanvas* canvas = surface->getCanvas();
|
||||
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
SkRandom rand;
|
||||
|
||||
const SkScalar half = cellSize * SK_ScalarHalf;
|
||||
const char* s = "01234567890!@#$%^&*=+<>?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
paint.setTextSize(28);
|
||||
paint.setTextAlign(SkPaint::kCenter_Align);
|
||||
int i = 0;
|
||||
for (int y = 0; y < atlasSize; y += cellSize) {
|
||||
for (int x = 0; x < atlasSize; x += cellSize) {
|
||||
paint.setColor(rand.nextU());
|
||||
paint.setAlpha(0xFF);
|
||||
int index = i % strlen(s);
|
||||
canvas->drawText(&s[index], 1, x + half, y + half + half/2, paint);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
return surface->newImageSnapshot();
|
||||
}
|
||||
|
||||
class DrawAtlasDrawable : public SkDrawable {
|
||||
enum {
|
||||
kMaxScale = 2,
|
||||
kCellSize = 32,
|
||||
kAtlasSize = 512,
|
||||
};
|
||||
|
||||
struct Rec {
|
||||
SkPoint fCenter;
|
||||
SkVector fVelocity;
|
||||
SkScalar fScale;
|
||||
SkScalar fDScale;
|
||||
SkScalar fRadian;
|
||||
SkScalar fDRadian;
|
||||
SkScalar fAlpha;
|
||||
SkScalar fDAlpha;
|
||||
|
||||
void advance(const SkRect& bounds) {
|
||||
fCenter += fVelocity;
|
||||
if (fCenter.fX > bounds.right()) {
|
||||
SkASSERT(fVelocity.fX > 0);
|
||||
fVelocity.fX = -fVelocity.fX;
|
||||
} else if (fCenter.fX < bounds.left()) {
|
||||
SkASSERT(fVelocity.fX < 0);
|
||||
fVelocity.fX = -fVelocity.fX;
|
||||
}
|
||||
if (fCenter.fY > bounds.bottom()) {
|
||||
SkASSERT(fVelocity.fY > 0);
|
||||
fVelocity.fY = -fVelocity.fY;
|
||||
} else if (fCenter.fY < bounds.top()) {
|
||||
SkASSERT(fVelocity.fY < 0);
|
||||
fVelocity.fY = -fVelocity.fY;
|
||||
}
|
||||
|
||||
fScale += fDScale;
|
||||
if (fScale > 2 || fScale < SK_Scalar1/2) {
|
||||
fDScale = -fDScale;
|
||||
}
|
||||
|
||||
fRadian += fDRadian;
|
||||
fRadian = SkScalarMod(fRadian, 2 * SK_ScalarPI);
|
||||
|
||||
fAlpha += fDAlpha;
|
||||
if (fAlpha > 1) {
|
||||
fAlpha = 1;
|
||||
fDAlpha = -fDAlpha;
|
||||
} else if (fAlpha < 0) {
|
||||
fAlpha = 0;
|
||||
fDAlpha = -fDAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
SkRSXform asRSXform() const {
|
||||
SkMatrix m;
|
||||
m.setTranslate(-8, -8);
|
||||
m.postScale(fScale, fScale);
|
||||
m.postRotate(SkRadiansToDegrees(fRadian));
|
||||
m.postTranslate(fCenter.fX, fCenter.fY);
|
||||
|
||||
SkRSXform x;
|
||||
x.fSCos = m.getScaleX();
|
||||
x.fSSin = m.getSkewY();
|
||||
x.fTx = m.getTranslateX();
|
||||
x.fTy = m.getTranslateY();
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
enum {
|
||||
N = 256,
|
||||
};
|
||||
|
||||
SkAutoTUnref<SkImage> fAtlas;
|
||||
Rec fRec[N];
|
||||
SkRect fTex[N];
|
||||
SkRect fBounds;
|
||||
bool fUseColors;
|
||||
|
||||
public:
|
||||
DrawAtlasDrawable(const SkRect& r) : fBounds(r), fUseColors(false) {
|
||||
SkRandom rand;
|
||||
fAtlas.reset(make_atlas(kAtlasSize, kCellSize));
|
||||
const SkScalar kMaxSpeed = 5;
|
||||
const SkScalar cell = SkIntToScalar(kCellSize);
|
||||
int i = 0;
|
||||
for (int y = 0; y < kAtlasSize; y += kCellSize) {
|
||||
for (int x = 0; x < kAtlasSize; x += kCellSize) {
|
||||
const SkScalar sx = SkIntToScalar(x);
|
||||
const SkScalar sy = SkIntToScalar(y);
|
||||
fTex[i].setXYWH(sx, sy, cell, cell);
|
||||
|
||||
fRec[i].fCenter.set(sx + cell/2, sy + 3*cell/4);
|
||||
fRec[i].fVelocity.fX = rand.nextSScalar1() * kMaxSpeed;
|
||||
fRec[i].fVelocity.fY = rand.nextSScalar1() * kMaxSpeed;
|
||||
fRec[i].fScale = 1;
|
||||
fRec[i].fDScale = rand.nextSScalar1() / 4;
|
||||
fRec[i].fRadian = 0;
|
||||
fRec[i].fDRadian = rand.nextSScalar1() / 8;
|
||||
fRec[i].fAlpha = rand.nextUScalar1();
|
||||
fRec[i].fDAlpha = rand.nextSScalar1() / 10;
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void toggleUseColors() {
|
||||
fUseColors = !fUseColors;
|
||||
}
|
||||
|
||||
protected:
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkRSXform xform[N];
|
||||
SkColor colors[N];
|
||||
|
||||
for (int i = 0; i < N; ++i) {
|
||||
fRec[i].advance(fBounds);
|
||||
xform[i] = fRec[i].asRSXform();
|
||||
if (fUseColors) {
|
||||
colors[i] = SkColorSetARGB((int)(fRec[i].fAlpha * 0xFF), 0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
}
|
||||
SkPaint paint;
|
||||
paint.setFilterQuality(kLow_SkFilterQuality);
|
||||
|
||||
const SkRect cull = this->getBounds();
|
||||
const SkColor* colorsPtr = fUseColors ? colors : NULL;
|
||||
canvas->drawAtlas(fAtlas, xform, fTex, colorsPtr, N, SkXfermode::kModulate_Mode,
|
||||
&cull, &paint);
|
||||
}
|
||||
|
||||
SkRect onGetBounds() override {
|
||||
const SkScalar border = kMaxScale * kCellSize;
|
||||
SkRect r = fBounds;
|
||||
r.outset(border, border);
|
||||
return r;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef SkDrawable INHERITED;
|
||||
};
|
||||
|
||||
class DrawAtlasView : public SampleView {
|
||||
DrawAtlasDrawable* fDrawable;
|
||||
|
||||
public:
|
||||
DrawAtlasView() {
|
||||
fDrawable = new DrawAtlasDrawable(SkRect::MakeWH(640, 480));
|
||||
}
|
||||
|
||||
~DrawAtlasView() override {
|
||||
fDrawable->unref();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool onQuery(SkEvent* evt) override {
|
||||
if (SampleCode::TitleQ(*evt)) {
|
||||
SampleCode::TitleR(evt, "DrawAtlas");
|
||||
return true;
|
||||
}
|
||||
SkUnichar uni;
|
||||
if (SampleCode::CharQ(*evt, &uni)) {
|
||||
switch (uni) {
|
||||
case 'C': fDrawable->toggleUseColors(); this->inval(NULL); return true;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return this->INHERITED::onQuery(evt);
|
||||
}
|
||||
|
||||
void onDrawContent(SkCanvas* canvas) override {
|
||||
canvas->drawDrawable(fDrawable);
|
||||
this->inval(NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO: switch over to use this for our animation
|
||||
bool onAnimate(const SkAnimTimer& timer) override {
|
||||
SkScalar angle = SkDoubleToScalar(fmod(timer.secs() * 360 / 24, 360));
|
||||
fAnimatingDrawable->setSweep(angle);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef SampleView INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkView* MyFactory() { return new DrawAtlasView; }
|
||||
static SkViewRegister reg(MyFactory);
|
@ -1801,6 +1801,18 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPai
|
||||
this->onDrawSprite(bitmap, left, top, paint);
|
||||
}
|
||||
|
||||
void SkCanvas::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode mode,
|
||||
const SkRect* cull, const SkPaint* paint) {
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
SkASSERT(atlas);
|
||||
SkASSERT(xform);
|
||||
SkASSERT(tex);
|
||||
this->onDrawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// These are the virtual drawing methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -2449,6 +2461,25 @@ void SkCanvas::onDrawDrawable(SkDrawable* dr) {
|
||||
dr->draw(this);
|
||||
}
|
||||
|
||||
void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode mode,
|
||||
const SkRect* cull, const SkPaint* paint) {
|
||||
if (cull && this->quickReject(*cull)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SkPaint pnt;
|
||||
if (paint) {
|
||||
pnt = *paint;
|
||||
}
|
||||
|
||||
LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, NULL)
|
||||
while (iter.next()) {
|
||||
iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, mode, pnt);
|
||||
}
|
||||
LOOPER_END
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// These methods are NOT virtual, and therefore must call back into virtual
|
||||
// methods, rather than actually drawing themselves.
|
||||
|
@ -5,6 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkDevice.h"
|
||||
#include "SkDraw.h"
|
||||
#include "SkDrawFilter.h"
|
||||
@ -13,6 +14,7 @@
|
||||
#include "SkPatchUtils.h"
|
||||
#include "SkPathMeasure.h"
|
||||
#include "SkRasterClip.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkTextToPathIter.h"
|
||||
@ -159,6 +161,37 @@ void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const
|
||||
}
|
||||
}
|
||||
|
||||
void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
|
||||
const SkRect tex[], const SkColor colors[], int count,
|
||||
SkXfermode::Mode mode, const SkPaint& paint) {
|
||||
SkPath path;
|
||||
path.setIsVolatile(true);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SkPoint quad[4];
|
||||
xform[i].toQuad(tex[i].width(), tex[i].height(), quad);
|
||||
|
||||
SkMatrix localM;
|
||||
localM.setRSXform(xform[i]);
|
||||
localM.preTranslate(-tex[i].left(), -tex[i].top());
|
||||
|
||||
SkPaint pnt(paint);
|
||||
pnt.setShader(atlas->newShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
|
||||
&localM))->unref();
|
||||
if (colors && colors[i] != SK_ColorWHITE) {
|
||||
SkAutoTUnref<SkColorFilter> cf(SkColorFilter::CreateModeFilter(colors[i], mode));
|
||||
pnt.setColorFilter(cf);
|
||||
}
|
||||
|
||||
path.rewind();
|
||||
path.addPoly(quad, 4, true);
|
||||
path.setConvexity(SkPath::kConvex_Convexity);
|
||||
this->drawPath(draw, path, pnt, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
|
||||
#ifdef SK_DEBUG
|
||||
SkASSERT(info.width() > 0 && info.height() > 0);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "SkMatrix.h"
|
||||
#include "SkFloatBits.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkString.h"
|
||||
#include "SkNx.h"
|
||||
|
||||
@ -440,6 +441,22 @@ void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, SkScalar px, SkScalar py)
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
}
|
||||
|
||||
SkMatrix& SkMatrix::setRSXform(const SkRSXform& xform) {
|
||||
fMat[kMScaleX] = xform.fSCos;
|
||||
fMat[kMSkewX] = -xform.fSSin;
|
||||
fMat[kMTransX] = xform.fTx;
|
||||
|
||||
fMat[kMSkewY] = xform.fSSin;
|
||||
fMat[kMScaleY] = xform.fSCos;
|
||||
fMat[kMTransY] = xform.fTy;
|
||||
|
||||
fMat[kMPersp0] = fMat[kMPersp1] = 0;
|
||||
fMat[kMPersp2] = 1;
|
||||
|
||||
this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
|
||||
fMat[kMScaleX] = cosV;
|
||||
fMat[kMSkewX] = -sinV;
|
||||
@ -1823,3 +1840,15 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkRSXform::toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const {
|
||||
quad[0].set(0, 0);
|
||||
quad[1].set(width, 0);
|
||||
quad[2].set(width, height);
|
||||
quad[3].set(0, height);
|
||||
SkMatrix m;
|
||||
m.setRSXform(*this).mapPoints(quad, quad, 4);
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,9 @@ enum DrawType {
|
||||
DRAW_TEXT_BLOB,
|
||||
DRAW_IMAGE,
|
||||
DRAW_IMAGE_RECT,
|
||||
DRAW_ATLAS,
|
||||
|
||||
LAST_DRAWTYPE_ENUM = DRAW_IMAGE_RECT
|
||||
LAST_DRAWTYPE_ENUM = DRAW_ATLAS
|
||||
};
|
||||
|
||||
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
|
||||
@ -85,6 +86,11 @@ enum DrawVertexFlags {
|
||||
DRAW_VERTICES_HAS_XFER = 0x08,
|
||||
};
|
||||
|
||||
enum DrawAtlasFlags {
|
||||
DRAW_ATLAS_HAS_COLORS = 1 << 0,
|
||||
DRAW_ATLAS_HAS_CULL = 1 << 1,
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// clipparams are packed in 5 bits
|
||||
// doAA:1 | regionOp:4
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SkPicturePlayback.h"
|
||||
#include "SkPictureRecord.h"
|
||||
#include "SkReader32.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkTypes.h"
|
||||
@ -156,6 +157,25 @@ void SkPicturePlayback::handleOp(SkReader32* reader,
|
||||
canvas->concat(matrix);
|
||||
break;
|
||||
}
|
||||
case DRAW_ATLAS: {
|
||||
const SkPaint* paint = fPictureData->getPaint(reader);
|
||||
const SkImage* atlas = fPictureData->getImage(reader);
|
||||
const uint32_t flags = reader->readU32();
|
||||
const int count = reader->readU32();
|
||||
const SkRSXform* xform = (const SkRSXform*)reader->skip(count * sizeof(SkRSXform));
|
||||
const SkRect* tex = (const SkRect*)reader->skip(count * sizeof(SkRect));
|
||||
const SkColor* colors = NULL;
|
||||
SkXfermode::Mode mode = SkXfermode::kDst_Mode;
|
||||
if (flags & DRAW_ATLAS_HAS_COLORS) {
|
||||
colors = (const SkColor*)reader->skip(count * sizeof(SkColor));
|
||||
mode = (SkXfermode::Mode)reader->readU32();
|
||||
}
|
||||
const SkRect* cull = NULL;
|
||||
if (flags & DRAW_ATLAS_HAS_CULL) {
|
||||
cull = (const SkRect*)reader->skip(sizeof(SkRect));
|
||||
}
|
||||
canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
|
||||
} break;
|
||||
case DRAW_BITMAP: {
|
||||
const SkPaint* paint = fPictureData->getPaint(reader);
|
||||
const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "SkPatchUtils.h"
|
||||
#include "SkPixelRef.h"
|
||||
#include "SkRRect.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkTSearch.h"
|
||||
|
||||
@ -99,6 +100,7 @@ static inline size_t get_paint_offset(DrawType op, size_t opSize) {
|
||||
1, // DRAW_TEXT_BLOB- right after op code
|
||||
1, // DRAW_IMAGE - right after op code
|
||||
1, // DRAW_IMAGE_RECT - right after op code
|
||||
1, // DRAW_ATLAS - right after op code
|
||||
};
|
||||
|
||||
SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1,
|
||||
@ -834,6 +836,42 @@ void SkPictureRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
void SkPictureRecord::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode mode,
|
||||
const SkRect* cull, const SkPaint* paint) {
|
||||
// [op + paint-index + atlas-index + flags + count] + [xform] + [tex] + [*colors + mode] + cull
|
||||
size_t size = 5 * kUInt32Size + count * sizeof(SkRSXform) + count * sizeof(SkRect);
|
||||
uint32_t flags = 0;
|
||||
if (colors) {
|
||||
flags |= DRAW_ATLAS_HAS_COLORS;
|
||||
size += count * sizeof(SkColor);
|
||||
size += sizeof(uint32_t); // xfermode::mode
|
||||
}
|
||||
if (cull) {
|
||||
flags |= DRAW_ATLAS_HAS_CULL;
|
||||
size += sizeof(SkRect);
|
||||
}
|
||||
|
||||
size_t initialOffset = this->addDraw(DRAW_ATLAS, &size);
|
||||
SkASSERT(initialOffset+get_paint_offset(DRAW_ATLAS, size) == fWriter.bytesWritten());
|
||||
this->addPaintPtr(paint);
|
||||
this->addImage(atlas);
|
||||
this->addInt(flags);
|
||||
this->addInt(count);
|
||||
fWriter.write(xform, count * sizeof(SkRSXform));
|
||||
fWriter.write(tex, count * sizeof(SkRect));
|
||||
|
||||
// write optional parameters
|
||||
if (colors) {
|
||||
fWriter.write(colors, count * sizeof(SkColor));
|
||||
this->addInt(mode);
|
||||
}
|
||||
if (cull) {
|
||||
fWriter.write(cull, sizeof(SkRect));
|
||||
}
|
||||
this->validate(initialOffset, size);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
|
||||
|
@ -173,6 +173,8 @@ protected:
|
||||
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||
const SkPaint& paint) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
|
||||
SkXfermode::Mode, const SkRect*, const SkPaint*) override;
|
||||
|
||||
void onDrawPaint(const SkPaint&) override;
|
||||
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
|
||||
|
@ -111,6 +111,7 @@ DRAW(DrawSprite, drawSprite(r.bitmap.shallowCopy(), r.left, r.top, r.paint));
|
||||
DRAW(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
|
||||
DRAW(DrawTextBlob, drawTextBlob(r.blob, r.x, r.y, r.paint));
|
||||
DRAW(DrawTextOnPath, drawTextOnPath(r.text, r.byteLength, r.path, &r.matrix, r.paint));
|
||||
DRAW(DrawAtlas, drawAtlas(r.atlas, r.xforms, r.texs, r.colors, r.count, r.mode, r.cull, r.paint));
|
||||
DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
|
||||
r.xmode.get(), r.indices, r.indexCount, r.paint));
|
||||
#undef DRAW
|
||||
@ -452,6 +453,14 @@ private:
|
||||
return this->adjustAndMap(dst, &op.paint);
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawAtlas& op) const {
|
||||
if (op.cull) {
|
||||
return this->adjustAndMap(*op.cull, op.paint);
|
||||
} else {
|
||||
return fCurrentClipBounds;
|
||||
}
|
||||
}
|
||||
|
||||
Bounds bounds(const DrawPicture& op) const {
|
||||
SkRect dst = op.picture->cullRect();
|
||||
op.matrix.mapRect(&dst);
|
||||
|
@ -299,6 +299,19 @@ void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
xmode);
|
||||
}
|
||||
|
||||
void SkRecorder::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode mode,
|
||||
const SkRect* cull, const SkPaint* paint) {
|
||||
APPEND(DrawAtlas, this->copy(paint),
|
||||
atlas,
|
||||
this->copy(xform, count),
|
||||
this->copy(tex, count),
|
||||
this->copy(colors, count),
|
||||
count,
|
||||
mode,
|
||||
this->copy(cull));
|
||||
}
|
||||
|
||||
void SkRecorder::willSave() {
|
||||
APPEND(Save);
|
||||
}
|
||||
|
@ -108,6 +108,8 @@ public:
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint&) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) override;
|
||||
|
||||
void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
|
||||
void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "SkDrawable.h"
|
||||
#include "SkPathPriv.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkTextBlob.h"
|
||||
|
||||
namespace SkRecords {
|
||||
@ -58,6 +59,7 @@ namespace SkRecords {
|
||||
M(DrawRect) \
|
||||
M(DrawSprite) \
|
||||
M(DrawTextBlob) \
|
||||
M(DrawAtlas) \
|
||||
M(DrawVertices)
|
||||
|
||||
// Defines SkRecords::Type, an enum of all record types.
|
||||
@ -121,6 +123,15 @@ struct T { \
|
||||
A a; B b; C c; D d; E e; \
|
||||
};
|
||||
|
||||
#define RECORD8(T, A, a, B, b, C, c, D, d, E, e, F, f, G, g, H, h) \
|
||||
struct T { \
|
||||
static const Type kType = T##_Type; \
|
||||
T() {} \
|
||||
template <typename Z, typename Y, typename X, typename W, typename V, typename U, typename S, typename R> \
|
||||
T(Z a, Y b, X c, W d, V e, U f, S g, R h) : a(a), b(b), c(c), d(d), e(e), f(f), g(g), h(h) {} \
|
||||
A a; B b; C c; D d; E e; F f; G g; H h; \
|
||||
};
|
||||
|
||||
#define ACT_AS_PTR(ptr) \
|
||||
operator T*() const { return ptr; } \
|
||||
T* operator->() const { return ptr; }
|
||||
@ -317,6 +328,15 @@ RECORD5(DrawPatch, SkPaint, paint,
|
||||
PODArray<SkPoint>, texCoords,
|
||||
RefBox<SkXfermode>, xmode);
|
||||
|
||||
RECORD8(DrawAtlas, Optional<SkPaint>, paint,
|
||||
RefBox<const SkImage>, atlas,
|
||||
PODArray<SkRSXform>, xforms,
|
||||
PODArray<SkRect>, texs,
|
||||
PODArray<SkColor>, colors,
|
||||
int, count,
|
||||
SkXfermode::Mode, mode,
|
||||
Optional<SkRect>, cull);
|
||||
|
||||
// This guy is so ugly we just write it manually.
|
||||
struct DrawVertices {
|
||||
static const Type kType = DrawVertices_Type;
|
||||
@ -357,6 +377,7 @@ struct DrawVertices {
|
||||
#undef RECORD3
|
||||
#undef RECORD4
|
||||
#undef RECORD5
|
||||
#undef RECORD8
|
||||
|
||||
} // namespace SkRecords
|
||||
|
||||
|
@ -39,6 +39,7 @@ enum DrawOps {
|
||||
kClipRect_DrawOp,
|
||||
kClipRRect_DrawOp,
|
||||
kConcat_DrawOp,
|
||||
kDrawAtlas_DrawOp,
|
||||
kDrawBitmap_DrawOp,
|
||||
kDrawBitmapNine_DrawOp,
|
||||
kDrawBitmapRectToRect_DrawOp,
|
||||
@ -144,6 +145,11 @@ enum {
|
||||
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
|
||||
kDrawVertices_HasXfermode_DrawOpFlag = 1 << 3,
|
||||
};
|
||||
enum {
|
||||
kDrawAtlas_HasPaint_DrawOpFlag = 1 << 0,
|
||||
kDrawAtlas_HasColors_DrawOpFlag = 1 << 1,
|
||||
kDrawAtlas_HasCull_DrawOpFlag = 1 << 2,
|
||||
};
|
||||
// These are shared between drawbitmap and drawimage
|
||||
enum {
|
||||
kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0,
|
||||
|
@ -20,11 +20,12 @@
|
||||
#include "SkDrawLooper.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkMaskFilter.h"
|
||||
#include "SkReadBuffer.h"
|
||||
#include "SkPatchUtils.h"
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkRasterizer.h"
|
||||
#include "SkReadBuffer.h"
|
||||
#include "SkRRect.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkTextBlob.h"
|
||||
#include "SkTypeface.h"
|
||||
@ -479,6 +480,33 @@ static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
}
|
||||
}
|
||||
|
||||
static void drawAtlas_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) {
|
||||
unsigned flags = DrawOp_unpackFlags(op32);
|
||||
|
||||
const SkPaint* paint = NULL;
|
||||
if (flags & kDrawAtlas_HasPaint_DrawOpFlag) {
|
||||
paint = &state->paint();
|
||||
}
|
||||
const int slot = reader->readU32();
|
||||
const SkImage* atlas = state->getImage(slot);
|
||||
const int count = reader->readU32();
|
||||
SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32();
|
||||
const SkRSXform* xform = skip<SkRSXform>(reader, count);
|
||||
const SkRect* tex = skip<SkRect>(reader, count);
|
||||
const SkColor* colors = NULL;
|
||||
if (flags & kDrawAtlas_HasColors_DrawOpFlag) {
|
||||
colors = skip<SkColor>(reader, count);
|
||||
}
|
||||
const SkRect* cull = NULL;
|
||||
if (flags & kDrawAtlas_HasCull_DrawOpFlag) {
|
||||
cull = skip<SkRect>(reader, 1);
|
||||
}
|
||||
|
||||
if (state->shouldDraw()) {
|
||||
canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||
@ -831,6 +859,7 @@ static const ReadProc gReadTable[] = {
|
||||
clipRect_rp,
|
||||
clipRRect_rp,
|
||||
concat_rp,
|
||||
drawAtlas_rp,
|
||||
drawBitmap_rp,
|
||||
drawBitmapNine_rp,
|
||||
drawBitmapRect_rp,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "SkGPipePriv.h"
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkMaskFilter.h"
|
||||
#include "SkRSXform.h"
|
||||
#include "SkWriteBuffer.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPatchUtils.h"
|
||||
@ -287,6 +288,8 @@ protected:
|
||||
const SkColor colors[], SkXfermode* xmode,
|
||||
const uint16_t indices[], int indexCount,
|
||||
const SkPaint&) override;
|
||||
void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[],
|
||||
int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) override;
|
||||
void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||
void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||
void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override;
|
||||
@ -1096,6 +1099,48 @@ void SkGPipeCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[],
|
||||
const SkColor colors[], int count, SkXfermode::Mode mode,
|
||||
const SkRect* cull, const SkPaint* paint) {
|
||||
NOTIFY_SETUP(this);
|
||||
unsigned flags = 0; // packs with the op, so needs no extra space
|
||||
|
||||
if (paint) {
|
||||
flags |= kDrawAtlas_HasPaint_DrawOpFlag;
|
||||
this->writePaint(*paint);
|
||||
}
|
||||
|
||||
size_t size = 4; // image-slot
|
||||
size += 4; // count
|
||||
size += 4; // mode
|
||||
size += count * sizeof(SkRSXform); // xform
|
||||
size += count * sizeof(SkRect); // tex
|
||||
if (colors) {
|
||||
flags |= kDrawAtlas_HasColors_DrawOpFlag;
|
||||
size += count * sizeof(SkColor); // colors
|
||||
}
|
||||
if (cull) {
|
||||
flags |= kDrawAtlas_HasCull_DrawOpFlag;
|
||||
size += sizeof(SkRect); // cull
|
||||
}
|
||||
|
||||
if (this->needOpBytes(size)) {
|
||||
this->writeOp(kDrawAtlas_DrawOp, flags, 0);
|
||||
int32_t slot = fImageHeap->insert(atlas);
|
||||
fWriter.write32(slot);
|
||||
fWriter.write32(count);
|
||||
fWriter.write32(mode);
|
||||
fWriter.write(xform, count * sizeof(SkRSXform));
|
||||
fWriter.write(tex, count * sizeof(SkRect));
|
||||
if (colors) {
|
||||
fWriter.write(colors, count * sizeof(SkColor));
|
||||
}
|
||||
if (cull) {
|
||||
fWriter.writeRect(*cull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||
const SkPaint& paint) {
|
||||
|
@ -251,6 +251,10 @@ protected:
|
||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||
const SkPaint& paint) override
|
||||
{SkASSERT(0);}
|
||||
void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
|
||||
const SkColor[], int count, SkXfermode::Mode, const SkPaint&) override
|
||||
{SkASSERT(0);}
|
||||
|
||||
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||
const SkPaint&) override
|
||||
{SkASSERT(0);}
|
||||
@ -356,8 +360,7 @@ bool SkDeferredDevice::hasPendingCommands() {
|
||||
return fPipeController.hasPendingCommands();
|
||||
}
|
||||
|
||||
void SkDeferredDevice::aboutToDraw()
|
||||
{
|
||||
void SkDeferredDevice::aboutToDraw() {
|
||||
if (fNotificationClient) {
|
||||
fNotificationClient->prepareForDraw();
|
||||
}
|
||||
@ -989,6 +992,15 @@ void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor color
|
||||
this->recordedDrawCommand();
|
||||
}
|
||||
|
||||
void SkDeferredCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[],
|
||||
const SkRect tex[], const SkColor colors[], int count,
|
||||
SkXfermode::Mode mode, const SkRect* cullRect,
|
||||
const SkPaint* paint) {
|
||||
AutoImmediateDrawIfNeeded autoDraw(*this, paint);
|
||||
this->drawingCanvas()->drawAtlas(atlas, xform, tex, colors, count, mode, cullRect, paint);
|
||||
this->recordedDrawCommand();
|
||||
}
|
||||
|
||||
SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
|
||||
this->drawingCanvas()->setDrawFilter(filter);
|
||||
this->INHERITED::setDrawFilter(filter);
|
||||
|
Loading…
Reference in New Issue
Block a user