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 "gm.h"
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkBlurImageFilter.h"
|
#include "SkBlurImageFilter.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
|
#include "SkSurface.h"
|
||||||
|
|
||||||
static void make_bm(SkBitmap* bm) {
|
static void make_bm(SkBitmap* bm) {
|
||||||
bm->allocN32Pixels(100, 100);
|
bm->allocN32Pixels(100, 100);
|
||||||
@ -93,7 +95,5 @@ protected:
|
|||||||
private:
|
private:
|
||||||
typedef GM INHERITED;
|
typedef GM INHERITED;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
DEF_GM( return new SpriteBitmapGM; )
|
DEF_GM( return new SpriteBitmapGM; )
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
'../samplecode/SampleAnimBlur.cpp',
|
'../samplecode/SampleAnimBlur.cpp',
|
||||||
'../samplecode/SampleApp.cpp',
|
'../samplecode/SampleApp.cpp',
|
||||||
'../samplecode/SampleArc.cpp',
|
'../samplecode/SampleArc.cpp',
|
||||||
|
'../samplecode/SampleAtlas.cpp',
|
||||||
'../samplecode/SampleBigBlur.cpp',
|
'../samplecode/SampleBigBlur.cpp',
|
||||||
'../samplecode/SampleBigGradient.cpp',
|
'../samplecode/SampleBigGradient.cpp',
|
||||||
'../samplecode/SampleBitmapRect.cpp',
|
'../samplecode/SampleBitmapRect.cpp',
|
||||||
|
@ -28,6 +28,7 @@ class SkImage;
|
|||||||
class SkMetaData;
|
class SkMetaData;
|
||||||
class SkPicture;
|
class SkPicture;
|
||||||
class SkRRect;
|
class SkRRect;
|
||||||
|
struct SkRSXform;
|
||||||
class SkSurface;
|
class SkSurface;
|
||||||
class SkSurface_Base;
|
class SkSurface_Base;
|
||||||
class SkTextBlob;
|
class SkTextBlob;
|
||||||
@ -1023,6 +1024,32 @@ public:
|
|||||||
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
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
|
* 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,
|
* (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[],
|
virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[],
|
||||||
const SkPoint texs[], const SkColor colors[], SkXfermode*,
|
const SkPoint texs[], const SkColor colors[], SkXfermode*,
|
||||||
const uint16_t indices[], int indexCount, const SkPaint&);
|
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 onDrawPath(const SkPath&, const SkPaint&);
|
||||||
virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
|
virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*);
|
||||||
virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*);
|
virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*);
|
||||||
|
@ -245,6 +245,11 @@ protected:
|
|||||||
// default implementation calls drawVertices
|
// default implementation calls drawVertices
|
||||||
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
|
||||||
const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
|
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
|
/** The SkDevice passed will be an SkDevice which was returned by a call to
|
||||||
onCreateDevice on this device with kNeverTile_TileExpectation.
|
onCreateDevice on this device with kNeverTile_TileExpectation.
|
||||||
*/
|
*/
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "SkRect.h"
|
#include "SkRect.h"
|
||||||
|
|
||||||
|
struct SkRSXform;
|
||||||
class SkString;
|
class SkString;
|
||||||
|
|
||||||
/** \class SkMatrix
|
/** \class SkMatrix
|
||||||
@ -244,6 +245,9 @@ public:
|
|||||||
/** Set the matrix to rotate by the specified sine and cosine values.
|
/** Set the matrix to rotate by the specified sine and cosine values.
|
||||||
*/
|
*/
|
||||||
void setSinCos(SkScalar sinValue, SkScalar cosValue);
|
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).
|
/** 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
|
The pivot point is the coordinate that should remain unchanged by the
|
||||||
specified transformation.
|
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 SkColor colors[], SkXfermode* xmode,
|
||||||
const uint16_t indices[], int indexCount,
|
const uint16_t indices[], int indexCount,
|
||||||
const SkPaint&) override;
|
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 onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||||
void onClipRRect(const SkRRect&, 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);
|
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
|
// These are the virtual drawing methods
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -2449,6 +2461,25 @@ void SkCanvas::onDrawDrawable(SkDrawable* dr) {
|
|||||||
dr->draw(this);
|
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
|
// These methods are NOT virtual, and therefore must call back into virtual
|
||||||
// methods, rather than actually drawing themselves.
|
// methods, rather than actually drawing themselves.
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "SkColorFilter.h"
|
||||||
#include "SkDevice.h"
|
#include "SkDevice.h"
|
||||||
#include "SkDraw.h"
|
#include "SkDraw.h"
|
||||||
#include "SkDrawFilter.h"
|
#include "SkDrawFilter.h"
|
||||||
@ -13,6 +14,7 @@
|
|||||||
#include "SkPatchUtils.h"
|
#include "SkPatchUtils.h"
|
||||||
#include "SkPathMeasure.h"
|
#include "SkPathMeasure.h"
|
||||||
#include "SkRasterClip.h"
|
#include "SkRasterClip.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkShader.h"
|
#include "SkShader.h"
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
#include "SkTextToPathIter.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) {
|
bool SkBaseDevice::readPixels(const SkImageInfo& info, void* dstP, size_t rowBytes, int x, int y) {
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
SkASSERT(info.width() > 0 && info.height() > 0);
|
SkASSERT(info.width() > 0 && info.height() > 0);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "SkMatrix.h"
|
#include "SkMatrix.h"
|
||||||
#include "SkFloatBits.h"
|
#include "SkFloatBits.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkString.h"
|
#include "SkString.h"
|
||||||
#include "SkNx.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);
|
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) {
|
void SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) {
|
||||||
fMat[kMScaleX] = cosV;
|
fMat[kMScaleX] = cosV;
|
||||||
fMat[kMSkewX] = -sinV;
|
fMat[kMSkewX] = -sinV;
|
||||||
@ -1823,3 +1840,15 @@ bool SkDecomposeUpper2x2(const SkMatrix& matrix,
|
|||||||
|
|
||||||
return true;
|
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_TEXT_BLOB,
|
||||||
DRAW_IMAGE,
|
DRAW_IMAGE,
|
||||||
DRAW_IMAGE_RECT,
|
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*
|
// In the 'match' method, this constant will match any flavor of DRAW_BITMAP*
|
||||||
@ -85,6 +86,11 @@ enum DrawVertexFlags {
|
|||||||
DRAW_VERTICES_HAS_XFER = 0x08,
|
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
|
// clipparams are packed in 5 bits
|
||||||
// doAA:1 | regionOp:4
|
// doAA:1 | regionOp:4
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "SkPicturePlayback.h"
|
#include "SkPicturePlayback.h"
|
||||||
#include "SkPictureRecord.h"
|
#include "SkPictureRecord.h"
|
||||||
#include "SkReader32.h"
|
#include "SkReader32.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
#include "SkTDArray.h"
|
#include "SkTDArray.h"
|
||||||
#include "SkTypes.h"
|
#include "SkTypes.h"
|
||||||
@ -156,6 +157,25 @@ void SkPicturePlayback::handleOp(SkReader32* reader,
|
|||||||
canvas->concat(matrix);
|
canvas->concat(matrix);
|
||||||
break;
|
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: {
|
case DRAW_BITMAP: {
|
||||||
const SkPaint* paint = fPictureData->getPaint(reader);
|
const SkPaint* paint = fPictureData->getPaint(reader);
|
||||||
const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
|
const SkBitmap bitmap = shallow_copy(fPictureData->getBitmap(reader));
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "SkPatchUtils.h"
|
#include "SkPatchUtils.h"
|
||||||
#include "SkPixelRef.h"
|
#include "SkPixelRef.h"
|
||||||
#include "SkRRect.h"
|
#include "SkRRect.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
#include "SkTSearch.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_TEXT_BLOB- right after op code
|
||||||
1, // DRAW_IMAGE - right after op code
|
1, // DRAW_IMAGE - right after op code
|
||||||
1, // DRAW_IMAGE_RECT - 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,
|
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);
|
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&) {
|
SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfaceProps&) {
|
||||||
|
@ -173,6 +173,8 @@ protected:
|
|||||||
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||||
const SkPaint& paint) override;
|
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 onDrawPaint(const SkPaint&) override;
|
||||||
void onDrawPoints(PointMode, size_t count, const SkPoint pts[], 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(DrawText, drawText(r.text, r.byteLength, r.x, r.y, r.paint));
|
||||||
DRAW(DrawTextBlob, drawTextBlob(r.blob, 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(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,
|
DRAW(DrawVertices, drawVertices(r.vmode, r.vertexCount, r.vertices, r.texs, r.colors,
|
||||||
r.xmode.get(), r.indices, r.indexCount, r.paint));
|
r.xmode.get(), r.indices, r.indexCount, r.paint));
|
||||||
#undef DRAW
|
#undef DRAW
|
||||||
@ -452,6 +453,14 @@ private:
|
|||||||
return this->adjustAndMap(dst, &op.paint);
|
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 {
|
Bounds bounds(const DrawPicture& op) const {
|
||||||
SkRect dst = op.picture->cullRect();
|
SkRect dst = op.picture->cullRect();
|
||||||
op.matrix.mapRect(&dst);
|
op.matrix.mapRect(&dst);
|
||||||
|
@ -299,6 +299,19 @@ void SkRecorder::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
|||||||
xmode);
|
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() {
|
void SkRecorder::willSave() {
|
||||||
APPEND(Save);
|
APPEND(Save);
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,8 @@ public:
|
|||||||
const SkColor colors[], SkXfermode* xmode,
|
const SkColor colors[], SkXfermode* xmode,
|
||||||
const uint16_t indices[], int indexCount,
|
const uint16_t indices[], int indexCount,
|
||||||
const SkPaint&) override;
|
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 onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) override;
|
||||||
void onClipRRect(const SkRRect& rrect, 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 "SkDrawable.h"
|
||||||
#include "SkPathPriv.h"
|
#include "SkPathPriv.h"
|
||||||
#include "SkPicture.h"
|
#include "SkPicture.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
|
|
||||||
namespace SkRecords {
|
namespace SkRecords {
|
||||||
@ -58,6 +59,7 @@ namespace SkRecords {
|
|||||||
M(DrawRect) \
|
M(DrawRect) \
|
||||||
M(DrawSprite) \
|
M(DrawSprite) \
|
||||||
M(DrawTextBlob) \
|
M(DrawTextBlob) \
|
||||||
|
M(DrawAtlas) \
|
||||||
M(DrawVertices)
|
M(DrawVertices)
|
||||||
|
|
||||||
// Defines SkRecords::Type, an enum of all record types.
|
// 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; \
|
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) \
|
#define ACT_AS_PTR(ptr) \
|
||||||
operator T*() const { return ptr; } \
|
operator T*() const { return ptr; } \
|
||||||
T* operator->() const { return ptr; }
|
T* operator->() const { return ptr; }
|
||||||
@ -317,6 +328,15 @@ RECORD5(DrawPatch, SkPaint, paint,
|
|||||||
PODArray<SkPoint>, texCoords,
|
PODArray<SkPoint>, texCoords,
|
||||||
RefBox<SkXfermode>, xmode);
|
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.
|
// This guy is so ugly we just write it manually.
|
||||||
struct DrawVertices {
|
struct DrawVertices {
|
||||||
static const Type kType = DrawVertices_Type;
|
static const Type kType = DrawVertices_Type;
|
||||||
@ -357,6 +377,7 @@ struct DrawVertices {
|
|||||||
#undef RECORD3
|
#undef RECORD3
|
||||||
#undef RECORD4
|
#undef RECORD4
|
||||||
#undef RECORD5
|
#undef RECORD5
|
||||||
|
#undef RECORD8
|
||||||
|
|
||||||
} // namespace SkRecords
|
} // namespace SkRecords
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ enum DrawOps {
|
|||||||
kClipRect_DrawOp,
|
kClipRect_DrawOp,
|
||||||
kClipRRect_DrawOp,
|
kClipRRect_DrawOp,
|
||||||
kConcat_DrawOp,
|
kConcat_DrawOp,
|
||||||
|
kDrawAtlas_DrawOp,
|
||||||
kDrawBitmap_DrawOp,
|
kDrawBitmap_DrawOp,
|
||||||
kDrawBitmapNine_DrawOp,
|
kDrawBitmapNine_DrawOp,
|
||||||
kDrawBitmapRectToRect_DrawOp,
|
kDrawBitmapRectToRect_DrawOp,
|
||||||
@ -144,6 +145,11 @@ enum {
|
|||||||
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
|
kDrawVertices_HasIndices_DrawOpFlag = 1 << 2,
|
||||||
kDrawVertices_HasXfermode_DrawOpFlag = 1 << 3,
|
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
|
// These are shared between drawbitmap and drawimage
|
||||||
enum {
|
enum {
|
||||||
kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0,
|
kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0,
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
#include "SkDrawLooper.h"
|
#include "SkDrawLooper.h"
|
||||||
#include "SkImageFilter.h"
|
#include "SkImageFilter.h"
|
||||||
#include "SkMaskFilter.h"
|
#include "SkMaskFilter.h"
|
||||||
#include "SkReadBuffer.h"
|
|
||||||
#include "SkPatchUtils.h"
|
#include "SkPatchUtils.h"
|
||||||
#include "SkPathEffect.h"
|
#include "SkPathEffect.h"
|
||||||
#include "SkRasterizer.h"
|
#include "SkRasterizer.h"
|
||||||
|
#include "SkReadBuffer.h"
|
||||||
#include "SkRRect.h"
|
#include "SkRRect.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkShader.h"
|
#include "SkShader.h"
|
||||||
#include "SkTextBlob.h"
|
#include "SkTextBlob.h"
|
||||||
#include "SkTypeface.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,
|
static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32,
|
||||||
@ -831,6 +859,7 @@ static const ReadProc gReadTable[] = {
|
|||||||
clipRect_rp,
|
clipRect_rp,
|
||||||
clipRRect_rp,
|
clipRRect_rp,
|
||||||
concat_rp,
|
concat_rp,
|
||||||
|
drawAtlas_rp,
|
||||||
drawBitmap_rp,
|
drawBitmap_rp,
|
||||||
drawBitmapNine_rp,
|
drawBitmapNine_rp,
|
||||||
drawBitmapRect_rp,
|
drawBitmapRect_rp,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "SkGPipePriv.h"
|
#include "SkGPipePriv.h"
|
||||||
#include "SkImageFilter.h"
|
#include "SkImageFilter.h"
|
||||||
#include "SkMaskFilter.h"
|
#include "SkMaskFilter.h"
|
||||||
|
#include "SkRSXform.h"
|
||||||
#include "SkWriteBuffer.h"
|
#include "SkWriteBuffer.h"
|
||||||
#include "SkPaint.h"
|
#include "SkPaint.h"
|
||||||
#include "SkPatchUtils.h"
|
#include "SkPatchUtils.h"
|
||||||
@ -287,6 +288,8 @@ protected:
|
|||||||
const SkColor colors[], SkXfermode* xmode,
|
const SkColor colors[], SkXfermode* xmode,
|
||||||
const uint16_t indices[], int indexCount,
|
const uint16_t indices[], int indexCount,
|
||||||
const SkPaint&) override;
|
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 onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||||
void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
|
void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override;
|
||||||
void onClipPath(const SkPath&, 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],
|
void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
|
||||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||||
const SkPaint& paint) {
|
const SkPaint& paint) {
|
||||||
|
@ -251,6 +251,10 @@ protected:
|
|||||||
const SkPoint texCoords[4], SkXfermode* xmode,
|
const SkPoint texCoords[4], SkXfermode* xmode,
|
||||||
const SkPaint& paint) override
|
const SkPaint& paint) override
|
||||||
{SkASSERT(0);}
|
{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,
|
void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
|
||||||
const SkPaint&) override
|
const SkPaint&) override
|
||||||
{SkASSERT(0);}
|
{SkASSERT(0);}
|
||||||
@ -356,8 +360,7 @@ bool SkDeferredDevice::hasPendingCommands() {
|
|||||||
return fPipeController.hasPendingCommands();
|
return fPipeController.hasPendingCommands();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkDeferredDevice::aboutToDraw()
|
void SkDeferredDevice::aboutToDraw() {
|
||||||
{
|
|
||||||
if (fNotificationClient) {
|
if (fNotificationClient) {
|
||||||
fNotificationClient->prepareForDraw();
|
fNotificationClient->prepareForDraw();
|
||||||
}
|
}
|
||||||
@ -989,6 +992,15 @@ void SkDeferredCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor color
|
|||||||
this->recordedDrawCommand();
|
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) {
|
SkDrawFilter* SkDeferredCanvas::setDrawFilter(SkDrawFilter* filter) {
|
||||||
this->drawingCanvas()->setDrawFilter(filter);
|
this->drawingCanvas()->setDrawFilter(filter);
|
||||||
this->INHERITED::setDrawFilter(filter);
|
this->INHERITED::setDrawFilter(filter);
|
||||||
|
Loading…
Reference in New Issue
Block a user