Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(822)

Unified Diff: src/pdf/SkPDFShader.cpp

Issue 842253003: SkPDFCanon (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/pdf/SkPDFShader.h ('K') | « src/pdf/SkPDFShader.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFShader.cpp
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 40f7d93f8907b30ab5c9ae191c449c60fa292879..ec92742b6ea76e253f4e87ea7f1223cc4631aded 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -10,6 +10,7 @@
#include "SkPDFShader.h"
#include "SkData.h"
+#include "SkPDFCanon.h"
#include "SkPDFCatalog.h"
#include "SkPDFDevice.h"
#include "SkPDFFormXObject.h"
@@ -475,7 +476,7 @@ static void drawBitmapMatrix(SkCanvas* canvas, const SkBitmap& bm, const SkMatri
canvas->drawBitmap(bm, 0, 0);
}
-class SkPDFShader::State {
+class SkPDFShaderState {
public:
SkShader::GradientType fType;
SkShader::GradientInfo fInfo;
@@ -488,35 +489,41 @@ public:
uint32_t fPixelGeneration;
SkShader::TileMode fImageTileModes[2];
- State(const SkShader& shader, const SkMatrix& canvasTransform,
- const SkIRect& bbox);
+ SkPDFShaderState(const SkShader& shader,
+ const SkMatrix& canvasTransform,
+ const SkIRect& bbox);
- bool operator==(const State& b) const;
+ bool operator==(const SkPDFShaderState& b) const;
- SkPDFShader::State* CreateAlphaToLuminosityState() const;
- SkPDFShader::State* CreateOpaqueState() const;
+ SkPDFShaderState* CreateAlphaToLuminosityState() const;
+ SkPDFShaderState* CreateOpaqueState() const;
bool GradientHasAlpha() const;
private:
- State(const State& other);
- State operator=(const State& rhs);
+ SkPDFShaderState(const SkPDFShaderState& other);
+ SkPDFShaderState operator=(const SkPDFShaderState& rhs);
void AllocateGradientInfoStorage();
};
class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader {
SK_DECLARE_INST_COUNT(SkPDFFunctionShader)
public:
- explicit SkPDFFunctionShader(SkPDFShader::State* state);
+ explicit SkPDFFunctionShader(SkPDFShaderState* state);
virtual ~SkPDFFunctionShader() {
if (isValid()) {
- RemoveShader(this);
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
+ SkPDFCanon::GetCanon().removeShader(this);
}
fResources.unrefAll();
}
bool isValid() SK_OVERRIDE { return fResources.count() > 0; }
+ virtual SkPDFObject* toPDFObject() SK_OVERRIDE {
+ return this;
+ }
+
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
GetResourcesHelper(&fResources,
@@ -528,7 +535,6 @@ private:
static SkPDFObject* RangeObject();
SkTDArray<SkPDFObject*> fResources;
- SkAutoTDelete<const SkPDFShader::State> fState;
SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
typedef SkPDFDict INHERITED;
@@ -541,10 +547,11 @@ private:
*/
class SkPDFAlphaFunctionShader : public SkPDFStream, public SkPDFShader {
public:
- explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
+ explicit SkPDFAlphaFunctionShader(SkPDFShaderState* state);
virtual ~SkPDFAlphaFunctionShader() {
if (isValid()) {
- RemoveShader(this);
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
+ SkPDFCanon::GetCanon().removeShader(this);
}
}
@@ -552,9 +559,11 @@ public:
return fColorShader.get() != NULL;
}
-private:
- SkAutoTDelete<const SkPDFShader::State> fState;
+ virtual SkPDFObject* toPDFObject() SK_OVERRIDE {
+ return this;
+ }
+private:
SkPDFGraphicState* CreateSMaskGraphicState();
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
@@ -570,16 +579,21 @@ private:
class SkPDFImageShader : public SkPDFStream, public SkPDFShader {
public:
- explicit SkPDFImageShader(SkPDFShader::State* state);
+ explicit SkPDFImageShader(SkPDFShaderState* state);
virtual ~SkPDFImageShader() {
if (isValid()) {
- RemoveShader(this);
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
+ SkPDFCanon::GetCanon().removeShader(this);
}
fResources.unrefAll();
}
bool isValid() SK_OVERRIDE { return size() > 0; }
+ virtual SkPDFObject* toPDFObject() SK_OVERRIDE {
+ return this;
+ }
+
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
GetResourcesHelper(&fResources.toArray(),
@@ -589,16 +603,26 @@ public:
private:
SkTSet<SkPDFObject*> fResources;
- SkAutoTDelete<const SkPDFShader::State> fState;
};
-SkPDFShader::SkPDFShader() {}
+SkPDFShader::SkPDFShader(const SkPDFShaderState* state)
+ : fPDFShaderState(state) {
+}
-// static
-SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
- SkPDFObject* result;
+SkPDFShader::~SkPDFShader() {
+}
+
+bool SkPDFShader::equals(const SkPDFShaderState& state) const {
+ return state == this->pdfShaderState();
+}
+
+const SkPDFShaderState& SkPDFShader::pdfShaderState() const {
+ return *fPDFShaderState;
+}
- SkAutoTDelete<State> shaderState(inState);
+// static
+SkPDFObject* SkPDFShader::GetPDFShaderByState(SkPDFShaderState* inState) {
+ SkAutoTDelete<SkPDFShaderState> shaderState(inState);
if (shaderState.get()->fType == SkShader::kNone_GradientType &&
shaderState.get()->fImage.isNull()) {
// TODO(vandebo) This drops SKComposeShader on the floor. We could
@@ -608,77 +632,57 @@ SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
return NULL;
}
- ShaderCanonicalEntry entry(NULL, shaderState.get());
- int index = CanonicalShaders().find(entry);
- if (index >= 0) {
- result = CanonicalShaders()[index].fPDFShader;
- result->ref();
- return result;
+ SkPDFShader* pdfShader = SkPDFCanon::GetCanon().findShader(*shaderState);
+ if (pdfShader) {
+ return SkRef(pdfShader->toPDFObject());
}
- bool valid = false;
// The PDFShader takes ownership of the shaderSate.
- if (shaderState.get()->fType == SkShader::kNone_GradientType) {
+ if (shaderState->fType == SkShader::kNone_GradientType) {
SkPDFImageShader* imageShader =
new SkPDFImageShader(shaderState.detach());
- valid = imageShader->isValid();
- result = imageShader;
- } else {
- if (shaderState.get()->GradientHasAlpha()) {
- SkPDFAlphaFunctionShader* gradientShader =
+ if (imageShader->isValid()) {
mtklein 2015/01/20 21:59:52 Might want to extract this if-else block as add_to
hal.canary 2015/01/21 17:07:51 GREAT idea
+ SkPDFCanon::GetCanon().addShader(imageShader);
+ return imageShader->toPDFObject();
+ } else {
+ SkDELETE(imageShader);
+ return NULL;
+ }
+ } else if (shaderState->GradientHasAlpha()) {
+ SkPDFAlphaFunctionShader* gradientShader =
SkNEW_ARGS(SkPDFAlphaFunctionShader, (shaderState.detach()));
- valid = gradientShader->isValid();
- result = gradientShader;
+ if (gradientShader->isValid()) {
+ SkPDFCanon::GetCanon().addShader(gradientShader);
+ return gradientShader->toPDFObject();
} else {
- SkPDFFunctionShader* functionShader =
+ SkDELETE(gradientShader);
+ return NULL;
+ }
+ } else {
+ SkPDFFunctionShader* functionShader =
SkNEW_ARGS(SkPDFFunctionShader, (shaderState.detach()));
- valid = functionShader->isValid();
- result = functionShader;
+ if (functionShader->isValid()) {
+ SkPDFCanon::GetCanon().addShader(functionShader);
+ return functionShader->toPDFObject();
+ } else {
+ SkDELETE(functionShader);
+ return NULL;
}
}
- if (!valid) {
- delete result;
- return NULL;
- }
- entry.fPDFShader = result;
- CanonicalShaders().push(entry);
- return result; // return the reference that came from new.
-}
-
-// static
-void SkPDFShader::RemoveShader(SkPDFObject* shader) {
- SkAutoMutexAcquire lock(CanonicalShadersMutex());
- ShaderCanonicalEntry entry(shader, NULL);
- int index = CanonicalShaders().find(entry);
- SkASSERT(index >= 0);
- CanonicalShaders().removeShuffle(index);
}
// static
SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
const SkMatrix& matrix,
const SkIRect& surfaceBBox) {
- SkAutoMutexAcquire lock(CanonicalShadersMutex());
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
return GetPDFShaderByState(
- SkNEW_ARGS(State, (shader, matrix, surfaceBBox)));
-}
-
-// static
-SkTDArray<SkPDFShader::ShaderCanonicalEntry>& SkPDFShader::CanonicalShaders() {
- SkPDFShader::CanonicalShadersMutex().assertHeld();
- static SkTDArray<ShaderCanonicalEntry> gCanonicalShaders;
- return gCanonicalShaders;
-}
-
-SK_DECLARE_STATIC_MUTEX(gCanonicalShadersMutex);
-// static
-SkBaseMutex& SkPDFShader::CanonicalShadersMutex() {
- return gCanonicalShadersMutex;
+ SkNEW_ARGS(SkPDFShaderState, (shader, matrix, surfaceBBox)));
}
// static
SkPDFObject* SkPDFFunctionShader::RangeObject() {
- SkPDFShader::CanonicalShadersMutex().assertHeld();
+ SkPDFCanon::GetShaderMutex().assertHeld();
static SkPDFArray* range = NULL;
// This method is only used with CanonicalShadersMutex, so it's safe to
// populate domain.
@@ -756,11 +760,10 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) {
*/
SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(this->pdfShaderState().fBBox);
- SkAutoTUnref<SkPDFObject> luminosityShader(
- SkPDFShader::GetPDFShaderByState(
- fState->CreateAlphaToLuminosityState()));
+ SkAutoTUnref<SkPDFObject> luminosityShader(SkPDFShader::GetPDFShaderByState(
+ this->pdfShaderState().CreateAlphaToLuminosityState()));
SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
@@ -775,10 +778,10 @@ SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
SkPDFGraphicState::kLuminosity_SMaskMode);
}
-SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
- : fState(state) {
+SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShaderState* state)
+ : SkPDFShader(state) {
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(this->pdfShaderState().fBBox);
fColorShader.reset(
SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState()));
@@ -835,19 +838,18 @@ static bool split_perspective(const SkMatrix in, SkMatrix* affine,
return true;
}
-SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
- : SkPDFDict("Pattern"),
- fState(state) {
+SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShaderState* state)
+ : SkPDFDict("Pattern"), SkPDFShader(state) {
SkString (*codeFunction)(const SkShader::GradientInfo& info,
const SkMatrix& perspectiveRemover) = NULL;
SkPoint transformPoints[2];
// Depending on the type of the gradient, we want to transform the
// coordinate space in different ways.
- const SkShader::GradientInfo* info = &fState.get()->fInfo;
+ const SkShader::GradientInfo* info = &this->pdfShaderState().fInfo;
mtklein 2015/01/20 21:59:52 Why don't we just write "this->pdfShaderState()" a
hal.canary 2015/01/21 17:07:51 Done.
transformPoints[0] = info->fPoint[0];
transformPoints[1] = info->fPoint[1];
- switch (fState.get()->fType) {
+ switch (this->pdfShaderState().fType) {
case SkShader::kLinear_GradientType:
codeFunction = &linearCode;
break;
@@ -892,8 +894,8 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
SkMatrix mapperMatrix;
unitToPointsMatrix(transformPoints, &mapperMatrix);
- SkMatrix finalMatrix = fState.get()->fCanvasTransform;
- finalMatrix.preConcat(fState.get()->fShaderTransform);
+ SkMatrix finalMatrix = this->pdfShaderState().fCanvasTransform;
+ finalMatrix.preConcat(this->pdfShaderState().fShaderTransform);
finalMatrix.preConcat(mapperMatrix);
// Preserves as much as posible in the final matrix, and only removes
@@ -910,7 +912,7 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
}
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(this->pdfShaderState().fBBox);
if (!inverseTransformBBox(finalMatrix, &bbox)) {
return;
}
@@ -923,10 +925,11 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
domain->appendScalar(bbox.fBottom);
SkString functionCode;
- // The two point radial gradient further references fState.get()->fInfo
+ // The two point radial gradient further references
+ // this->pdfShaderState().fInfo
// in translating from x, y coordinates to the t parameter. So, we have
// to transform the points and radii according to the calculated matrix.
- if (fState.get()->fType == SkShader::kRadial2_GradientType) {
+ if (this->pdfShaderState().fType == SkShader::kRadial2_GradientType) {
SkShader::GradientInfo twoPointRadialInfo = *info;
SkMatrix inverseMapperMatrix;
if (!mapperMatrix.invert(&inverseMapperMatrix)) {
@@ -956,8 +959,9 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
insert("Shading", pdfShader.get());
}
-SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
- fState.get()->fImage.lockPixels();
+SkPDFImageShader::SkPDFImageShader(SkPDFShaderState* state)
+ : SkPDFShader(state) {
+ this->pdfShaderState().fImage.lockPixels();
// The image shader pattern cell will be drawn into a separate device
// in pattern cell space (no scaling on the bitmap, though there may be
@@ -965,15 +969,15 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
// Map clip bounds to shader space to ensure the device is large enough
// to handle fake clamping.
- SkMatrix finalMatrix = fState.get()->fCanvasTransform;
- finalMatrix.preConcat(fState.get()->fShaderTransform);
+ SkMatrix finalMatrix = this->pdfShaderState().fCanvasTransform;
+ finalMatrix.preConcat(this->pdfShaderState().fShaderTransform);
SkRect deviceBounds;
- deviceBounds.set(fState.get()->fBBox);
+ deviceBounds.set(this->pdfShaderState().fBBox);
if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
return;
}
- const SkBitmap* image = &fState.get()->fImage;
+ const SkBitmap* image = &this->pdfShaderState().fImage;
SkRect bitmapBounds;
image->getBounds(&bitmapBounds);
@@ -982,8 +986,8 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
// For clamp modes, we're only interested in the clip region, whether
// or not the main bitmap is in it.
SkShader::TileMode tileModes[2];
- tileModes[0] = fState.get()->fImageTileModes[0];
- tileModes[1] = fState.get()->fImageTileModes[1];
+ tileModes[0] = this->pdfShaderState().fImageTileModes[0];
+ tileModes[1] = this->pdfShaderState().fImageTileModes[1];
if (tileModes[0] != SkShader::kClamp_TileMode ||
tileModes[1] != SkShader::kClamp_TileMode) {
deviceBounds.join(bitmapBounds);
@@ -1163,7 +1167,7 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
populate_tiling_pattern_dict(this, patternBBox,
pattern.getResourceDict(), finalMatrix);
- fState.get()->fImage.unlockPixels();
+ this->pdfShaderState().fImage.unlockPixels();
}
SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFArray* domain) {
@@ -1175,17 +1179,7 @@ SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFAr
return result;
}
-SkPDFShader::ShaderCanonicalEntry::ShaderCanonicalEntry(SkPDFObject* pdfShader, const State* state)
- : fPDFShader(pdfShader)
- , fState(state)
-{}
-
-bool SkPDFShader::ShaderCanonicalEntry::operator==(const ShaderCanonicalEntry& b) const {
- return fPDFShader == b.fPDFShader ||
- (fState != NULL && b.fState != NULL && *fState == *b.fState);
-}
-
-bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
+bool SkPDFShaderState::operator==(const SkPDFShaderState& b) const {
if (fType != b.fType ||
fCanvasTransform != b.fCanvasTransform ||
fShaderTransform != b.fShaderTransform ||
@@ -1239,11 +1233,10 @@ bool SkPDFShader::State::operator==(const SkPDFShader::State& b) const {
return true;
}
-SkPDFShader::State::State(const SkShader& shader,
- const SkMatrix& canvasTransform, const SkIRect& bbox)
- : fCanvasTransform(canvasTransform),
- fBBox(bbox),
- fPixelGeneration(0) {
+SkPDFShaderState::SkPDFShaderState(const SkShader& shader,
+ const SkMatrix& canvasTransform,
+ const SkIRect& bbox)
+ : fCanvasTransform(canvasTransform), fBBox(bbox), fPixelGeneration(0) {
fInfo.fColorCount = 0;
fInfo.fColors = NULL;
fInfo.fColorOffsets = NULL;
@@ -1268,12 +1261,11 @@ SkPDFShader::State::State(const SkShader& shader,
}
}
-SkPDFShader::State::State(const SkPDFShader::State& other)
- : fType(other.fType),
- fCanvasTransform(other.fCanvasTransform),
- fShaderTransform(other.fShaderTransform),
- fBBox(other.fBBox)
-{
+SkPDFShaderState::SkPDFShaderState(const SkPDFShaderState& other)
+ : fType(other.fType)
+ , fCanvasTransform(other.fCanvasTransform)
+ , fShaderTransform(other.fShaderTransform)
+ , fBBox(other.fBBox) {
// Only gradients supported for now, since that is all that is used.
// If needed, image state copy constructor can be added here later.
SkASSERT(fType != SkShader::kNone_GradientType);
@@ -1293,10 +1285,10 @@ SkPDFShader::State::State(const SkPDFShader::State& other)
* Create a copy of this gradient state with alpha assigned to RGB luminousity.
* Only valid for gradient states.
*/
-SkPDFShader::State* SkPDFShader::State::CreateAlphaToLuminosityState() const {
+SkPDFShaderState* SkPDFShaderState::CreateAlphaToLuminosityState() const {
SkASSERT(fType != SkShader::kNone_GradientType);
- SkPDFShader::State* newState = new SkPDFShader::State(*this);
+ SkPDFShaderState* newState = new SkPDFShaderState(*this);
for (int i = 0; i < fInfo.fColorCount; i++) {
SkAlpha alpha = SkColorGetA(fInfo.fColors[i]);
@@ -1310,10 +1302,10 @@ SkPDFShader::State* SkPDFShader::State::CreateAlphaToLuminosityState() const {
* Create a copy of this gradient state with alpha set to fully opaque
* Only valid for gradient states.
*/
-SkPDFShader::State* SkPDFShader::State::CreateOpaqueState() const {
+SkPDFShaderState* SkPDFShaderState::CreateOpaqueState() const {
SkASSERT(fType != SkShader::kNone_GradientType);
- SkPDFShader::State* newState = new SkPDFShader::State(*this);
+ SkPDFShaderState* newState = new SkPDFShaderState(*this);
for (int i = 0; i < fInfo.fColorCount; i++) {
newState->fInfo.fColors[i] = SkColorSetA(fInfo.fColors[i],
SK_AlphaOPAQUE);
@@ -1325,7 +1317,7 @@ SkPDFShader::State* SkPDFShader::State::CreateOpaqueState() const {
/**
* Returns true if state is a gradient and the gradient has alpha.
*/
-bool SkPDFShader::State::GradientHasAlpha() const {
+bool SkPDFShaderState::GradientHasAlpha() const {
if (fType == SkShader::kNone_GradientType) {
return false;
}
@@ -1339,7 +1331,7 @@ bool SkPDFShader::State::GradientHasAlpha() const {
return false;
}
-void SkPDFShader::State::AllocateGradientInfoStorage() {
+void SkPDFShaderState::AllocateGradientInfoStorage() {
fColorData.set(sk_malloc_throw(
fInfo.fColorCount * (sizeof(SkColor) + sizeof(SkScalar))));
fInfo.fColors = reinterpret_cast<SkColor*>(fColorData.get());
« src/pdf/SkPDFShader.h ('K') | « src/pdf/SkPDFShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698