Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrDrawState.cpp
1 /*
2  * Copyright 2012 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "GrDrawState.h"
9
10 #include "GrOptDrawState.h"
11 #include "GrPaint.h"
12
13 //////////////////////////////////////////////////////////////////////////////s
14
15 GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const {
16     if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) {
17         GrBlendCoeff srcCoeff;
18         GrBlendCoeff dstCoeff;
19         BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
20         fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoeff, dstCoeff, caps));
21         fCachedCapsID = caps.getUniqueID();
22     } else {
23 #ifdef SK_DEBUG
24         GrBlendCoeff srcCoeff;
25         GrBlendCoeff dstCoeff;
26         BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoeff);
27         SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) == *fCachedOptState);
28 #endif
29     }
30     fCachedOptState->ref();
31     return fCachedOptState;
32 }
33
34 //////////////////////////////////////////////////////////////////////////////s
35
36 GrDrawState::CombinedState GrDrawState::CombineIfPossible(
37     const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
38
39     if (!a.isEqual(b)) {
40         return kIncompatible_CombinedState;
41     }
42
43     // If the general draw states are equal (from check above) we know hasColorVertexAttribute()
44     // is equivalent for both a and b
45     if (a.hasColorVertexAttribute()) {
46         // If one is opaque and the other is not then the combined state is not opaque. Moreover,
47         // if the opaqueness affects the ability to get color/coverage blending correct then we
48         // don't combine the draw states.
49         bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
50         bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
51         if (aIsOpaque != bIsOpaque) {
52             const GrDrawState* opaque;
53             const GrDrawState* nonOpaque;
54             if (aIsOpaque) {
55                 opaque = &a;
56                 nonOpaque = &b;
57             } else {
58                 opaque = &b;
59                 nonOpaque = &a;
60             }
61             if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
62                 SkASSERT(!nonOpaque->hasSolidCoverage());
63                 if (!nonOpaque->couldApplyCoverage(caps)) {
64                     return kIncompatible_CombinedState;
65                 }
66             }
67             return aIsOpaque ? kB_CombinedState : kA_CombinedState;
68         }
69     }
70     return kAOrB_CombinedState;
71 }
72
73 //////////////////////////////////////////////////////////////////////////////s
74
75 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix)
76     : fCachedOptState(NULL) {
77     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
78     *this = state;
79     if (!preConcatMatrix.isIdentity()) {
80         if (this->hasGeometryProcessor()) {
81             fGeometryProcessor->localCoordChange(preConcatMatrix);
82         }
83         for (int i = 0; i < this->numColorStages(); ++i) {
84             fColorStages[i].localCoordChange(preConcatMatrix);
85         }
86         for (int i = 0; i < this->numCoverageStages(); ++i) {
87             fCoverageStages[i].localCoordChange(preConcatMatrix);
88         }
89         this->invalidateOptState();
90     }
91 }
92
93 GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
94     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
95     SkASSERT(!that.fRenderTarget.ownsPendingIO());
96     SkASSERT(!this->fRenderTarget.ownsPendingIO());
97     this->setRenderTarget(that.getRenderTarget());
98     fColor = that.fColor;
99     fViewMatrix = that.fViewMatrix;
100     fSrcBlend = that.fSrcBlend;
101     fDstBlend = that.fDstBlend;
102     fBlendConstant = that.fBlendConstant;
103     fFlagBits = that.fFlagBits;
104     fVACount = that.fVACount;
105     fVAPtr = that.fVAPtr;
106     fVAStride = that.fVAStride;
107     fStencilSettings = that.fStencilSettings;
108     fCoverage = that.fCoverage;
109     fDrawFace = that.fDrawFace;
110     if (that.hasGeometryProcessor()) {
111         fGeometryProcessor.reset(SkNEW_ARGS(GrGeometryStage, (*that.fGeometryProcessor.get())));
112     } else {
113         fGeometryProcessor.reset(NULL);
114     }
115     fColorStages = that.fColorStages;
116     fCoverageStages = that.fCoverageStages;
117
118     fHints = that.fHints;
119
120     SkRefCnt_SafeAssign(fCachedOptState, that.fCachedOptState);
121
122     memcpy(fFixedFunctionVertexAttribIndices,
123             that.fFixedFunctionVertexAttribIndices,
124             sizeof(fFixedFunctionVertexAttribIndices));
125     return *this;
126 }
127
128 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
129     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
130     SkASSERT(!fRenderTarget.ownsPendingIO());
131
132     fGeometryProcessor.reset(NULL);
133     fColorStages.reset();
134     fCoverageStages.reset();
135
136     fRenderTarget.reset();
137
138     this->setDefaultVertexAttribs();
139
140     fColor = 0xffffffff;
141     if (NULL == initialViewMatrix) {
142         fViewMatrix.reset();
143     } else {
144         fViewMatrix = *initialViewMatrix;
145     }
146     fSrcBlend = kOne_GrBlendCoeff;
147     fDstBlend = kZero_GrBlendCoeff;
148     fBlendConstant = 0x0;
149     fFlagBits = 0x0;
150     fStencilSettings.setDisabled();
151     fCoverage = 0xff;
152     fDrawFace = kBoth_DrawFace;
153
154     fHints = 0;
155
156     this->invalidateOptState();
157 }
158
159 bool GrDrawState::setIdentityViewMatrix()  {
160     if (this->numTotalStages()) {
161         SkMatrix invVM;
162         if (!fViewMatrix.invert(&invVM)) {
163             // sad trombone sound
164             return false;
165         }
166         if (this->hasGeometryProcessor()) {
167             fGeometryProcessor->localCoordChange(invVM);
168         }
169         for (int s = 0; s < this->numColorStages(); ++s) {
170             fColorStages[s].localCoordChange(invVM);
171         }
172         for (int s = 0; s < this->numCoverageStages(); ++s) {
173             fCoverageStages[s].localCoordChange(invVM);
174         }
175     }
176     this->invalidateOptState();
177     fViewMatrix.reset();
178     return true;
179 }
180
181 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
182     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
183
184     fGeometryProcessor.reset(NULL);
185     fColorStages.reset();
186     fCoverageStages.reset();
187
188     for (int i = 0; i < paint.numColorStages(); ++i) {
189         fColorStages.push_back(paint.getColorStage(i));
190     }
191
192     for (int i = 0; i < paint.numCoverageStages(); ++i) {
193         fCoverageStages.push_back(paint.getCoverageStage(i));
194     }
195
196     this->setRenderTarget(rt);
197
198     fViewMatrix = vm;
199
200     // These have no equivalent in GrPaint, set them to defaults
201     fBlendConstant = 0x0;
202     fDrawFace = kBoth_DrawFace;
203     fStencilSettings.setDisabled();
204     this->resetStateFlags();
205     fHints = 0;
206
207     // Enable the clip bit
208     this->enableState(GrDrawState::kClip_StateBit);
209
210     this->setColor(paint.getColor());
211     this->setState(GrDrawState::kDither_StateBit, paint.isDither());
212     this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
213
214     this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
215     this->setCoverage(paint.getCoverage());
216     this->invalidateOptState();
217 }
218
219 ////////////////////////////////////////////////////////////////////////////////
220
221 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, size_t stride) {
222     // this works as long as we're 4 byte-aligned
223 #ifdef SK_DEBUG
224     uint32_t overlapCheck = 0;
225     SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt);
226     for (int index = 0; index < count; ++index) {
227         size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
228         size_t attribOffset = attribs[index].fOffset;
229         SkASSERT(attribOffset + attribSize <= stride);
230         size_t dwordCount = attribSize >> 2;
231         uint32_t mask = (1 << dwordCount)-1;
232         size_t offsetShift = attribOffset >> 2;
233         SkASSERT(!(overlapCheck & (mask << offsetShift)));
234         overlapCheck |= (mask << offsetShift);
235     }
236 #endif
237 }
238
239 ////////////////////////////////////////////////////////////////////////////////
240
241 void GrDrawState::internalSetVertexAttribs(const GrVertexAttrib* attribs, int count,
242                                            size_t stride) {
243     SkASSERT(count <= kMaxVertexAttribCnt);
244
245     fVAPtr = attribs;
246     fVACount = count;
247     fVAStride = stride;
248     validate_vertex_attribs(fVAPtr, fVACount, fVAStride);
249
250     // Set all the indices to -1
251     memset(fFixedFunctionVertexAttribIndices,
252            0xff,
253            sizeof(fFixedFunctionVertexAttribIndices));
254 #ifdef SK_DEBUG
255     uint32_t overlapCheck = 0;
256 #endif
257     for (int i = 0; i < count; ++i) {
258         if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
259             // The fixed function attribs can only be specified once
260             SkASSERT(-1 == fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
261             SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
262                      GrVertexAttribTypeVectorCount(attribs[i].fType));
263             fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
264         }
265 #ifdef SK_DEBUG
266         size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
267         uint32_t mask = (1 << dwordCount)-1;
268         size_t offsetShift = attribs[i].fOffset >> 2;
269         SkASSERT(!(overlapCheck & (mask << offsetShift)));
270         overlapCheck |= (mask << offsetShift);
271 #endif
272     }
273     this->invalidateOptState();
274     // Positions must be specified.
275     SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
276 }
277
278 ////////////////////////////////////////////////////////////////////////////////
279
280 void GrDrawState::setDefaultVertexAttribs() {
281     static const GrVertexAttrib kPositionAttrib =
282         {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
283
284     fVAPtr = &kPositionAttrib;
285     fVACount = 1;
286     fVAStride = GrVertexAttribTypeSize(kVec2f_GrVertexAttribType);
287
288     // set all the fixed function indices to -1 except position.
289     memset(fFixedFunctionVertexAttribIndices,
290            0xff,
291            sizeof(fFixedFunctionVertexAttribIndices));
292     fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
293     this->invalidateOptState();
294 }
295
296 ////////////////////////////////////////////////////////////////////////////////
297
298 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
299     if (caps.dualSourceBlendingSupport()) {
300         return true;
301     }
302     // we can correctly apply coverage if a) we have dual source blending
303     // or b) one of our blend optimizations applies
304     // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
305     GrBlendCoeff srcCoeff;
306     GrBlendCoeff dstCoeff;
307     BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
308     return GrRODrawState::kNone_BlendOpt != flag ||
309            (this->willEffectReadDstColor() &&
310             kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
311 }
312
313 //////////////////////////////////////////////////////////////////////////////
314
315 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawState) {
316     SkASSERT(drawState);
317     fDrawState = drawState;
318     fVAPtr = drawState->fVAPtr;
319     fVACount = drawState->fVACount;
320     fVAStride = drawState->fVAStride;
321     fDrawState->setDefaultVertexAttribs();
322 }
323
324 //////////////////////////////////////////////////////////////////////////////s
325
326 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
327     if (fDrawState) {
328         // See the big comment on the class definition about GPs.
329         if (SK_InvalidUniqueID == fOriginalGPID) {
330             fDrawState->fGeometryProcessor.reset(NULL);
331         } else {
332             SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniqueID() ==
333                      fOriginalGPID);
334             fOriginalGPID = SK_InvalidUniqueID;
335         }
336
337         int m = fDrawState->numColorStages() - fColorEffectCnt;
338         SkASSERT(m >= 0);
339         fDrawState->fColorStages.pop_back_n(m);
340
341         int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
342         SkASSERT(n >= 0);
343         fDrawState->fCoverageStages.pop_back_n(n);
344         if (m + n > 0) {
345             fDrawState->invalidateOptState();
346         }
347         SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
348     }
349     fDrawState = ds;
350     if (NULL != ds) {
351         SkASSERT(SK_InvalidUniqueID == fOriginalGPID);
352         if (NULL != ds->getGeometryProcessor()) {
353             fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqueID();
354         }
355         fColorEffectCnt = ds->numColorStages();
356         fCoverageEffectCnt = ds->numCoverageStages();
357         SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
358     }
359 }
360
361 ////////////////////////////////////////////////////////////////////////////////
362
363 void GrDrawState::AutoViewMatrixRestore::restore() {
364     if (fDrawState) {
365         SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
366         fDrawState->fViewMatrix = fViewMatrix;
367         SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
368         int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
369         SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
370
371         int i = 0;
372         if (fHasGeometryProcessor) {
373             SkASSERT(fDrawState->hasGeometryProcessor());
374             fDrawState->fGeometryProcessor->restoreCoordChange(fSavedCoordChanges[i++]);
375         }
376         for (int s = 0; s < fNumColorStages; ++s, ++i) {
377             fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
378         }
379         for (int s = 0; s < numCoverageStages; ++s, ++i) {
380             fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
381         }
382         fDrawState->invalidateOptState();
383         fDrawState = NULL;
384     }
385 }
386
387 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
388                                              const SkMatrix& preconcatMatrix) {
389     this->restore();
390
391     SkASSERT(NULL == fDrawState);
392     if (NULL == drawState || preconcatMatrix.isIdentity()) {
393         return;
394     }
395     fDrawState = drawState;
396
397     fViewMatrix = drawState->getViewMatrix();
398     drawState->fViewMatrix.preConcat(preconcatMatrix);
399
400     this->doEffectCoordChanges(preconcatMatrix);
401     SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
402     drawState->invalidateOptState();
403 }
404
405 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
406     this->restore();
407
408     if (NULL == drawState) {
409         return false;
410     }
411
412     if (drawState->getViewMatrix().isIdentity()) {
413         return true;
414     }
415
416     drawState->invalidateOptState();
417     fViewMatrix = drawState->getViewMatrix();
418     if (0 == drawState->numTotalStages()) {
419         drawState->fViewMatrix.reset();
420         fDrawState = drawState;
421         fHasGeometryProcessor = false;
422         fNumColorStages = 0;
423         fSavedCoordChanges.reset(0);
424         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
425         return true;
426     } else {
427         SkMatrix inv;
428         if (!fViewMatrix.invert(&inv)) {
429             return false;
430         }
431         drawState->fViewMatrix.reset();
432         fDrawState = drawState;
433         this->doEffectCoordChanges(inv);
434         SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
435         return true;
436     }
437 }
438
439 void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
440     fSavedCoordChanges.reset(fDrawState->numTotalStages());
441     int i = 0;
442
443     fHasGeometryProcessor = false;
444     if (fDrawState->hasGeometryProcessor()) {
445         fDrawState->fGeometryProcessor->saveCoordChange(&fSavedCoordChanges[i++]);
446         fDrawState->fGeometryProcessor->localCoordChange(coordChangeMatrix);
447         fHasGeometryProcessor = true;
448     }
449
450     fNumColorStages = fDrawState->numColorStages();
451     for (int s = 0; s < fNumColorStages; ++s, ++i) {
452         fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
453         fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
454     }
455
456     int numCoverageStages = fDrawState->numCoverageStages();
457     for (int s = 0; s < numCoverageStages; ++s, ++i) {
458         fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
459         fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
460     }
461 }
462
463 ////////////////////////////////////////////////////////////////////////////////
464
465 void GrDrawState::invalidateOptState() const {
466     SkSafeSetNull(fCachedOptState);
467 }
468
469 ////////////////////////////////////////////////////////////////////////////////
470
471 GrDrawState::~GrDrawState() {
472     SkSafeUnref(fCachedOptState);
473     SkASSERT(0 == fBlockEffectRemovalCnt);
474 }
475