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

Unified Diff: src/pdf/SkPDFShader.cpp

Issue 842253003: SkPDFCanon (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: did you mean struct here? 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
« no previous file with comments | « 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 890bf447d5c46a8b0e4943ab0704bfef233195d7..2a144a6926f6a63a456cdb16038ea924d83c2e87 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"
@@ -509,13 +510,12 @@ class SkPDFFunctionShader : public SkPDFDict, public SkPDFShader {
public:
explicit SkPDFFunctionShader(SkPDFShader::State* state);
virtual ~SkPDFFunctionShader() {
- if (isValid()) {
- RemoveShader(this);
- }
+ SkPDFShader::RemoveFromCanonIfValid(this);
fResources.unrefAll();
}
bool isValid() SK_OVERRIDE { return fResources.count() > 0; }
+ SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
@@ -528,7 +528,6 @@ private:
static SkPDFObject* RangeObject();
SkTDArray<SkPDFObject*> fResources;
- SkAutoTDelete<const SkPDFShader::State> fState;
SkPDFStream* makePSFunction(const SkString& psCode, SkPDFArray* domain);
typedef SkPDFDict INHERITED;
@@ -543,18 +542,15 @@ class SkPDFAlphaFunctionShader : public SkPDFStream, public SkPDFShader {
public:
explicit SkPDFAlphaFunctionShader(SkPDFShader::State* state);
virtual ~SkPDFAlphaFunctionShader() {
- if (isValid()) {
- RemoveShader(this);
- }
+ SkPDFShader::RemoveFromCanonIfValid(this);
}
bool isValid() SK_OVERRIDE {
return fColorShader.get() != NULL;
}
+ SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
private:
- SkAutoTDelete<const SkPDFShader::State> fState;
-
SkPDFGraphicState* CreateSMaskGraphicState();
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
@@ -572,13 +568,12 @@ class SkPDFImageShader : public SkPDFStream, public SkPDFShader {
public:
explicit SkPDFImageShader(SkPDFShader::State* state);
virtual ~SkPDFImageShader() {
- if (isValid()) {
- RemoveShader(this);
- }
+ SkPDFShader::RemoveFromCanonIfValid(this);
fResources.unrefAll();
}
bool isValid() SK_OVERRIDE { return size() > 0; }
+ SkPDFObject* toPDFObject() SK_OVERRIDE { return this; }
void getResources(const SkTSet<SkPDFObject*>& knownResourceObjects,
SkTSet<SkPDFObject*>* newResourceObjects) SK_OVERRIDE {
@@ -589,18 +584,37 @@ public:
private:
SkTSet<SkPDFObject*> fResources;
- SkAutoTDelete<const SkPDFShader::State> fState;
};
-SkPDFShader::SkPDFShader() {}
+SkPDFShader::SkPDFShader(SkPDFShader::State* s) : fShaderState(s) {}
+
+SkPDFShader::~SkPDFShader() {}
+
+void SkPDFShader::RemoveFromCanonIfValid(SkPDFShader* shader) {
+ if (shader->isValid()) {
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
+ SkPDFCanon::GetCanon().removeShader(shader);
+ }
+}
+
+bool SkPDFShader::equals(const SkPDFShader::State& state) const {
+ return state == *fShaderState.get();
+}
+
+SkPDFObject* SkPDFShader::AddToCanonIfValid(SkPDFShader* shader) {
+ if (!shader->isValid()) {
+ SkDELETE(shader);
+ return NULL;
+ }
+ SkPDFCanon::GetCanon().addShader(shader);
+ return shader->toPDFObject();
+}
// static
SkPDFObject* SkPDFShader::GetPDFShaderByState(State* inState) {
- SkPDFObject* result;
-
- SkAutoTDelete<State> shaderState(inState);
- if (shaderState.get()->fType == SkShader::kNone_GradientType &&
- shaderState.get()->fImage.isNull()) {
+ SkAutoTDelete<State> state(inState);
+ if (state->fType == SkShader::kNone_GradientType &&
+ state->fImage.isNull()) {
// TODO(vandebo) This drops SKComposeShader on the floor. We could
// handle compose shader by pulling things up to a layer, drawing with
// the first shader, applying the xfer mode and drawing again with the
@@ -608,50 +622,23 @@ 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(*state);
+ if (pdfShader) {
+ SkASSERT(pdfShader->isValid());
+ return SkRef(pdfShader->toPDFObject());
}
- bool valid = false;
// The PDFShader takes ownership of the shaderSate.
- if (shaderState.get()->fType == SkShader::kNone_GradientType) {
- SkPDFImageShader* imageShader =
- new SkPDFImageShader(shaderState.detach());
- valid = imageShader->isValid();
- result = imageShader;
+ if (state->fType == SkShader::kNone_GradientType) {
+ return SkPDFShader::AddToCanonIfValid(
+ SkNEW_ARGS(SkPDFImageShader, (state.detach())));
+ } else if (state->GradientHasAlpha()) {
+ return SkPDFShader::AddToCanonIfValid(
+ SkNEW_ARGS(SkPDFAlphaFunctionShader, (state.detach())));
} else {
- if (shaderState.get()->GradientHasAlpha()) {
- SkPDFAlphaFunctionShader* gradientShader =
- SkNEW_ARGS(SkPDFAlphaFunctionShader, (shaderState.detach()));
- valid = gradientShader->isValid();
- result = gradientShader;
- } else {
- SkPDFFunctionShader* functionShader =
- SkNEW_ARGS(SkPDFFunctionShader, (shaderState.detach()));
- valid = functionShader->isValid();
- result = functionShader;
- }
- }
- if (!valid) {
- delete result;
- return NULL;
+ return SkPDFShader::AddToCanonIfValid(
+ SkNEW_ARGS(SkPDFFunctionShader, (state.detach())));
}
- 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
@@ -659,27 +646,15 @@ SkPDFObject* SkPDFShader::GetPDFShader(const SkShader& shader,
const SkMatrix& matrix,
const SkIRect& surfaceBBox,
SkScalar rasterScale) {
- SkAutoMutexAcquire lock(CanonicalShadersMutex());
+ SkAutoMutexAcquire lock(SkPDFCanon::GetShaderMutex());
return GetPDFShaderByState(
SkNEW_ARGS(State, (shader, matrix, surfaceBBox, rasterScale)));
}
-// 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;
-}
// 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.
@@ -757,11 +732,10 @@ static SkStream* create_pattern_fill_content(int gsIndex, SkRect& bounds) {
*/
SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(fShaderState->fBBox);
- SkAutoTUnref<SkPDFObject> luminosityShader(
- SkPDFShader::GetPDFShaderByState(
- fState->CreateAlphaToLuminosityState()));
+ SkAutoTUnref<SkPDFObject> luminosityShader(SkPDFShader::GetPDFShaderByState(
+ fShaderState->CreateAlphaToLuminosityState()));
SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
@@ -777,9 +751,9 @@ SkPDFGraphicState* SkPDFAlphaFunctionShader::CreateSMaskGraphicState() {
}
SkPDFAlphaFunctionShader::SkPDFAlphaFunctionShader(SkPDFShader::State* state)
- : fState(state) {
+ : SkPDFShader(state) {
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(fShaderState->fBBox);
fColorShader.reset(
SkPDFShader::GetPDFShaderByState(state->CreateOpaqueState()));
@@ -837,18 +811,17 @@ static bool split_perspective(const SkMatrix in, SkMatrix* affine,
}
SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
- : SkPDFDict("Pattern"),
- fState(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 = &fShaderState->fInfo;
transformPoints[0] = info->fPoint[0];
transformPoints[1] = info->fPoint[1];
- switch (fState.get()->fType) {
+ switch (fShaderState->fType) {
case SkShader::kLinear_GradientType:
codeFunction = &linearCode;
break;
@@ -893,8 +866,8 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
SkMatrix mapperMatrix;
unitToPointsMatrix(transformPoints, &mapperMatrix);
- SkMatrix finalMatrix = fState.get()->fCanvasTransform;
- finalMatrix.preConcat(fState.get()->fShaderTransform);
+ SkMatrix finalMatrix = fShaderState->fCanvasTransform;
+ finalMatrix.preConcat(fShaderState->fShaderTransform);
finalMatrix.preConcat(mapperMatrix);
// Preserves as much as posible in the final matrix, and only removes
@@ -911,7 +884,7 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
}
SkRect bbox;
- bbox.set(fState.get()->fBBox);
+ bbox.set(fShaderState->fBBox);
if (!inverseTransformBBox(finalMatrix, &bbox)) {
return;
}
@@ -924,10 +897,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
+ // fShaderState->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 (fShaderState->fType == SkShader::kRadial2_GradientType) {
SkShader::GradientInfo twoPointRadialInfo = *info;
SkMatrix inverseMapperMatrix;
if (!mapperMatrix.invert(&inverseMapperMatrix)) {
@@ -957,8 +931,9 @@ SkPDFFunctionShader::SkPDFFunctionShader(SkPDFShader::State* state)
insert("Shading", pdfShader.get());
}
-SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
- fState.get()->fImage.lockPixels();
+SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state)
+ : SkPDFShader(state) {
+ fShaderState->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
@@ -966,15 +941,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 = fShaderState->fCanvasTransform;
+ finalMatrix.preConcat(fShaderState->fShaderTransform);
SkRect deviceBounds;
- deviceBounds.set(fState.get()->fBBox);
+ deviceBounds.set(fShaderState->fBBox);
if (!inverseTransformBBox(finalMatrix, &deviceBounds)) {
return;
}
- const SkBitmap* image = &fState.get()->fImage;
+ const SkBitmap* image = &fShaderState->fImage;
SkRect bitmapBounds;
image->getBounds(&bitmapBounds);
@@ -983,8 +958,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] = fShaderState->fImageTileModes[0];
+ tileModes[1] = fShaderState->fImageTileModes[1];
if (tileModes[0] != SkShader::kClamp_TileMode ||
tileModes[1] != SkShader::kClamp_TileMode) {
deviceBounds.join(bitmapBounds);
@@ -1164,7 +1139,7 @@ SkPDFImageShader::SkPDFImageShader(SkPDFShader::State* state) : fState(state) {
populate_tiling_pattern_dict(this, patternBBox,
pattern.getResourceDict(), finalMatrix);
- fState.get()->fImage.unlockPixels();
+ fShaderState->fImage.unlockPixels();
}
SkPDFStream* SkPDFFunctionShader::makePSFunction(const SkString& psCode, SkPDFArray* domain) {
@@ -1176,16 +1151,6 @@ 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 {
if (fType != b.fType ||
fCanvasTransform != b.fCanvasTransform ||
« no previous file with comments | « src/pdf/SkPDFShader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698