void GrGLProgram::setMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState& optState) { // Load the RT height uniform if it is needed to y-flip gl_FragCoord. if (fBuiltinUniformHandles.fRTHeightUni.isValid() && fMatrixState.fRenderTargetSize.fHeight != optState.getRenderTarget()->height()) { fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(optState.getRenderTarget()->height())); } // call subclasses to set the actual view matrix this->onSetMatrixAndRenderTargetHeight(drawType, optState); }
void GrGLNvprProgramBase::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState& optState) { SkASSERT(GrGpu::IsPathRenderingDrawType(drawType)); const GrRenderTarget* rt = optState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); fGpu->glPathRendering()->setProjectionMatrix(optState.getViewMatrix(), size, rt->origin()); }
void GrGLProgram::onSetMatrixAndRenderTargetHeight(GrGpu::DrawType drawType, const GrOptDrawState& optState) { const GrRenderTarget* rt = optState.getRenderTarget(); SkISize size; size.set(rt->width(), rt->height()); if (fMatrixState.fRenderTargetOrigin != rt->origin() || fMatrixState.fRenderTargetSize != size || !fMatrixState.fViewMatrix.cheapEqualTo(optState.getViewMatrix())) { SkASSERT(fBuiltinUniformHandles.fViewMatrixUni.isValid()); fMatrixState.fViewMatrix = optState.getViewMatrix(); fMatrixState.fRenderTargetSize = size; fMatrixState.fRenderTargetOrigin = rt->origin(); GrGLfloat viewMatrix[3 * 3]; fMatrixState.getGLMatrix<3>(viewMatrix); fProgramDataManager.setMatrix3f(fBuiltinUniformHandles.fViewMatrixUni, viewMatrix); GrGLfloat rtAdjustmentVec[4]; fMatrixState.getRTAdjustmentVec(rtAdjustmentVec); fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec); } }
bool GrGLProgramDescBuilder::Build(const GrOptDrawState& optState, const GrProgramDesc::DescInfo& descInfo, GrGpu::DrawType drawType, GrGpuGL* gpu, const GrDeviceCoordTexture* dstCopy, GrProgramDesc* desc) { bool inputColorIsUsed = descInfo.fInputColorIsUsed; bool inputCoverageIsUsed = descInfo.fInputCoverageIsUsed; // The descriptor is used as a cache key. Thus when a field of the // descriptor will not affect program generation (because of the attribute // bindings in use or other descriptor field settings) it should be set // to a canonical value to avoid duplicate programs with different keys. bool requiresLocalCoordAttrib = descInfo.fRequiresLocalCoordAttrib; int numStages = optState.numTotalStages(); GR_STATIC_ASSERT(0 == kProcessorKeyOffsetsAndLengthOffset % sizeof(uint32_t)); // Make room for everything up to and including the array of offsets to effect keys. desc->fKey.reset(); desc->fKey.push_back_n(kProcessorKeyOffsetsAndLengthOffset + 2 * sizeof(uint16_t) * numStages); int offsetAndSizeIndex = 0; // We can only have one effect which touches the vertex shader if (optState.hasGeometryProcessor()) { if (!BuildStagedProcessorKey<GeometryProcessorKeyBuilder>(*optState.getGeometryProcessor(), gpu->glCaps(), false, desc, &offsetAndSizeIndex)) { return false; } } for (int s = 0; s < optState.numFragmentStages(); ++s) { if (!BuildStagedProcessorKey<FragmentProcessorKeyBuilder>(optState.getFragmentStage(s), gpu->glCaps(), requiresLocalCoordAttrib, desc, &offsetAndSizeIndex)) { return false; } } // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------------------------- // Because header is a pointer into the dynamic array, we can't push any new data into the key // below here. GLKeyHeader* header = desc->atOffset<GLKeyHeader, kHeaderOffset>(); // make sure any padding in the header is zeroed. memset(header, 0, kHeaderSize); header->fHasGeometryProcessor = optState.hasGeometryProcessor(); header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; bool isPathRendering = GrGpu::IsPathRenderingDrawType(drawType); if (gpu->caps()->pathRenderingSupport() && isPathRendering) { header->fUseNvpr = true; SkASSERT(!optState.hasGeometryProcessor()); } else { header->fUseNvpr = false; } bool hasUniformColor = inputColorIsUsed && (isPathRendering || !descInfo.hasColorVertexAttribute()); bool hasUniformCoverage = inputCoverageIsUsed && (isPathRendering || !descInfo.hasCoverageVertexAttribute()); if (!inputColorIsUsed) { header->fColorInput = GrProgramDesc::kAllOnes_ColorInput; } else if (hasUniformColor) { header->fColorInput = GrProgramDesc::kUniform_ColorInput; } else { header->fColorInput = GrProgramDesc::kAttribute_ColorInput; SkASSERT(!header->fUseNvpr); } bool covIsSolidWhite = !descInfo.hasCoverageVertexAttribute() && 0xffffffff == optState.getCoverageColor(); if (covIsSolidWhite || !inputCoverageIsUsed) { header->fCoverageInput = GrProgramDesc::kAllOnes_ColorInput; } else if (hasUniformCoverage) { header->fCoverageInput = GrProgramDesc::kUniform_ColorInput; } else { header->fCoverageInput = GrProgramDesc::kAttribute_ColorInput; SkASSERT(!header->fUseNvpr); } if (descInfo.fReadsDst) { SkASSERT(dstCopy || gpu->caps()->dstReadInShaderSupport()); const GrTexture* dstCopyTexture = NULL; if (dstCopy) { dstCopyTexture = dstCopy->texture(); } header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps()); SkASSERT(0 != header->fDstReadKey); } else { header->fDstReadKey = 0; } if (descInfo.fReadsFragPosition) { header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(optState.getRenderTarget(), gpu->glCaps()); } else { header->fFragPosKey = 0; } // Record attribute indices header->fPositionAttributeIndex = descInfo.positionAttributeIndex(); header->fLocalCoordAttributeIndex = descInfo.localCoordAttributeIndex(); // For constant color and coverage we need an attribute with an index beyond those already set int availableAttributeIndex = optState.getVertexAttribCount(); if (descInfo.hasColorVertexAttribute()) { header->fColorAttributeIndex = descInfo.colorVertexAttributeIndex(); } else if (GrProgramDesc::kAttribute_ColorInput == header->fColorInput) { SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); header->fColorAttributeIndex = availableAttributeIndex; availableAttributeIndex++; } else { header->fColorAttributeIndex = -1; } if (descInfo.hasCoverageVertexAttribute()) { header->fCoverageAttributeIndex = descInfo.coverageVertexAttributeIndex(); } else if (GrProgramDesc::kAttribute_ColorInput == header->fCoverageInput) { SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt); header->fCoverageAttributeIndex = availableAttributeIndex; } else { header->fCoverageAttributeIndex = -1; } header->fPrimaryOutputType = descInfo.fPrimaryOutputType; header->fSecondaryOutputType = descInfo.fSecondaryOutputType; header->fColorEffectCnt = optState.numColorStages(); header->fCoverageEffectCnt = optState.numCoverageStages(); desc->finalize(); return true; }