| /* |
| * Copyright 2012 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "GrDrawState.h" |
| |
| #include "GrPaint.h" |
| |
| void GrDrawState::setFromPaint(const GrPaint& paint) { |
| for (int i = 0; i < GrPaint::kMaxColorStages; ++i) { |
| int s = i + GrPaint::kFirstColorStage; |
| if (paint.isColorStageEnabled(i)) { |
| *this->stage(s) = paint.getColorStage(i); |
| } |
| } |
| |
| this->setFirstCoverageStage(GrPaint::kFirstCoverageStage); |
| |
| for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) { |
| int s = i + GrPaint::kFirstCoverageStage; |
| if (paint.isCoverageStageEnabled(i)) { |
| *this->stage(s) = paint.getCoverageStage(i); |
| } |
| } |
| |
| // disable all stages not accessible via the paint |
| for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) { |
| this->disableStage(s); |
| } |
| |
| this->setColor(paint.getColor()); |
| |
| this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| |
| this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode()); |
| this->setCoverage(paint.getCoverage()); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| void GrDrawState::AutoViewMatrixRestore::restore() { |
| if (NULL != fDrawState) { |
| fDrawState->setViewMatrix(fViewMatrix); |
| for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| if (fRestoreMask & (1 << s)) { |
| fDrawState->stage(s)->restoreCoordChange(fSavedCoordChanges[s]); |
| } |
| } |
| } |
| fDrawState = NULL; |
| } |
| |
| void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, |
| const SkMatrix& preconcatMatrix, |
| uint32_t explicitCoordStageMask) { |
| this->restore(); |
| |
| fDrawState = drawState; |
| if (NULL == drawState) { |
| return; |
| } |
| |
| fRestoreMask = 0; |
| fViewMatrix = drawState->getViewMatrix(); |
| drawState->preConcatViewMatrix(preconcatMatrix); |
| for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) { |
| fRestoreMask |= (1 << s); |
| fDrawState->stage(s)->saveCoordChange(&fSavedCoordChanges[s]); |
| drawState->stage(s)->preConcatCoordChange(preconcatMatrix); |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| void GrDrawState::AutoDeviceCoordDraw::restore() { |
| if (NULL != fDrawState) { |
| fDrawState->setViewMatrix(fViewMatrix); |
| for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| if (fRestoreMask & (1 << s)) { |
| fDrawState->stage(s)->restoreCoordChange(fSavedCoordChanges[s]); |
| } |
| } |
| } |
| fDrawState = NULL; |
| } |
| |
| bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState, |
| uint32_t explicitCoordStageMask) { |
| GrAssert(NULL != drawState); |
| |
| this->restore(); |
| |
| fDrawState = drawState; |
| if (NULL == fDrawState) { |
| return false; |
| } |
| |
| fViewMatrix = drawState->getViewMatrix(); |
| fRestoreMask = 0; |
| SkMatrix invVM; |
| bool inverted = false; |
| |
| for (int s = 0; s < GrDrawState::kNumStages; ++s) { |
| if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) { |
| if (!inverted && !fViewMatrix.invert(&invVM)) { |
| // sad trombone sound |
| fDrawState = NULL; |
| return false; |
| } else { |
| inverted = true; |
| } |
| fRestoreMask |= (1 << s); |
| GrEffectStage* stage = drawState->stage(s); |
| stage->saveCoordChange(&fSavedCoordChanges[s]); |
| stage->preConcatCoordChange(invVM); |
| } |
| } |
| drawState->viewMatrix()->reset(); |
| return true; |
| } |