OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkComposeShader.h" | 10 #include "SkComposeShader.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 }; | 66 }; |
67 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) | 67 #define SkAutoAlphaRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoAlphaRestore) |
68 | 68 |
69 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { | 69 void SkComposeShader::flatten(SkWriteBuffer& buffer) const { |
70 this->INHERITED::flatten(buffer); | 70 this->INHERITED::flatten(buffer); |
71 buffer.writeFlattenable(fShaderA); | 71 buffer.writeFlattenable(fShaderA); |
72 buffer.writeFlattenable(fShaderB); | 72 buffer.writeFlattenable(fShaderB); |
73 buffer.writeFlattenable(fMode); | 73 buffer.writeFlattenable(fMode); |
74 } | 74 } |
75 | 75 |
76 /* We call validContext/createContext on our two worker shaders. | 76 template <typename T> void safe_call_destructor(T* obj) { |
77 However, we always let them see opaque alpha, and if the paint | 77 if (obj) { |
78 really is translucent, then we apply that after the fact. | 78 obj->~T(); |
79 | |
80 */ | |
81 bool SkComposeShader::validContext(const ContextRec& rec, SkMatrix* totalInverse
) const { | |
82 if (!this->INHERITED::validContext(rec, totalInverse)) { | |
83 return false; | |
84 } | 79 } |
85 | |
86 // we preconcat our localMatrix (if any) with the device matrix | |
87 // before calling our sub-shaders | |
88 | |
89 SkMatrix tmpM; | |
90 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); | |
91 | |
92 ContextRec newRec(rec); | |
93 newRec.fMatrix = &tmpM; | |
94 | |
95 return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); | |
96 } | 80 } |
97 | 81 |
98 SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s
torage) const { | 82 SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void*
storage) const { |
99 if (!this->validContext(rec)) { | |
100 return NULL; | |
101 } | |
102 | |
103 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); | 83 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); |
104 char* bStorage = aStorage + fShaderA->contextSize(); | 84 char* bStorage = aStorage + fShaderA->contextSize(); |
105 | 85 |
106 // we preconcat our localMatrix (if any) with the device matrix | 86 // we preconcat our localMatrix (if any) with the device matrix |
107 // before calling our sub-shaders | 87 // before calling our sub-shaders |
108 SkMatrix tmpM; | 88 SkMatrix tmpM; |
109 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); | 89 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); |
110 | 90 |
111 // Our sub-shaders need to see opaque, so by combining them we don't double-
alphatize the | 91 // Our sub-shaders need to see opaque, so by combining them we don't double-
alphatize the |
112 // result. ComposeShader itself will respect the alpha, and post-apply it af
ter calling the | 92 // result. ComposeShader itself will respect the alpha, and post-apply it af
ter calling the |
113 // sub-shaders. | 93 // sub-shaders. |
114 SkPaint opaquePaint(*rec.fPaint); | 94 SkPaint opaquePaint(*rec.fPaint); |
115 opaquePaint.setAlpha(0xFF); | 95 opaquePaint.setAlpha(0xFF); |
116 | 96 |
117 ContextRec newRec(rec); | 97 ContextRec newRec(rec); |
118 newRec.fMatrix = &tmpM; | 98 newRec.fMatrix = &tmpM; |
119 newRec.fPaint = &opaquePaint; | 99 newRec.fPaint = &opaquePaint; |
120 | 100 |
121 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); | 101 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); |
122 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); | 102 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); |
123 | 103 if (!contextA || !contextB) { |
124 // Both functions must succeed; otherwise validContext should have returned | 104 safe_call_destructor(contextA); |
125 // false. | 105 safe_call_destructor(contextB); |
126 SkASSERT(contextA); | 106 return NULL; |
127 SkASSERT(contextB); | 107 } |
128 | 108 |
129 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont
extA, contextB)); | 109 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont
extA, contextB)); |
130 } | 110 } |
131 | 111 |
132 SkComposeShader::ComposeShaderContext::ComposeShaderContext( | 112 SkComposeShader::ComposeShaderContext::ComposeShaderContext( |
133 const SkComposeShader& shader, const ContextRec& rec, | 113 const SkComposeShader& shader, const ContextRec& rec, |
134 SkShader::Context* contextA, SkShader::Context* contextB) | 114 SkShader::Context* contextA, SkShader::Context* contextB) |
135 : INHERITED(shader, rec) | 115 : INHERITED(shader, rec) |
136 , fShaderContextA(contextA) | 116 , fShaderContextA(contextA) |
137 , fShaderContextB(contextB) {} | 117 , fShaderContextB(contextB) {} |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 str->append(" ShaderB: "); | 197 str->append(" ShaderB: "); |
218 fShaderB->toString(str); | 198 fShaderB->toString(str); |
219 str->append(" Xfermode: "); | 199 str->append(" Xfermode: "); |
220 fMode->toString(str); | 200 fMode->toString(str); |
221 | 201 |
222 this->INHERITED::toString(str); | 202 this->INHERITED::toString(str); |
223 | 203 |
224 str->append(")"); | 204 str->append(")"); |
225 } | 205 } |
226 #endif | 206 #endif |
OLD | NEW |