void GrDrawTarget::drawNonIndexed(GrPrimitiveType type, int startVertex, int vertexCount) { #if GR_DEBUG GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); int maxVertex = startVertex + vertexCount; int maxValidVertex; switch (geoSrc.fVertexSrc) { case kNone_GeometrySrcType: GrCrash("Attempting to draw non-indexed geom without vertex src."); case kReserved_GeometrySrcType: // fallthrough case kArray_GeometrySrcType: maxValidVertex = geoSrc.fVertexCount; break; case kBuffer_GeometrySrcType: maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / VertexSize(geoSrc.fVertexLayout); break; } if (maxVertex > maxValidVertex) { GrCrash("Non-indexed drawing outside valid vertex range."); } #endif if (vertexCount > 0) { this->onDrawNonIndexed(type, startVertex, vertexCount); } }
bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, int startIndex, int vertexCount, int indexCount) const { const GrDrawState& drawState = this->getDrawState(); #if GR_DEBUG const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); int maxVertex = startVertex + vertexCount; int maxValidVertex; switch (geoSrc.fVertexSrc) { case kNone_GeometrySrcType: GrCrash("Attempting to draw without vertex src."); case kReserved_GeometrySrcType: // fallthrough case kArray_GeometrySrcType: maxValidVertex = geoSrc.fVertexCount; break; case kBuffer_GeometrySrcType: maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / VertexSize(geoSrc.fVertexLayout); break; } if (maxVertex > maxValidVertex) { GrCrash("Drawing outside valid vertex range."); } if (indexCount > 0) { int maxIndex = startIndex + indexCount; int maxValidIndex; switch (geoSrc.fIndexSrc) { case kNone_GeometrySrcType: GrCrash("Attempting to draw indexed geom without index src."); case kReserved_GeometrySrcType: // fallthrough case kArray_GeometrySrcType: maxValidIndex = geoSrc.fIndexCount; break; case kBuffer_GeometrySrcType: maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t); break; } if (maxIndex > maxValidIndex) { GrCrash("Index reads outside valid index range."); } } GrAssert(NULL != drawState.getRenderTarget()); for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (drawState.isStageEnabled(s)) { const GrEffect* effect = drawState.getStage(s).getEffect(); int numTextures = effect->numTextures(); for (int t = 0; t < numTextures; ++t) { GrTexture* texture = effect->texture(t); GrAssert(texture->asRenderTarget() != drawState.getRenderTarget()); } } } #endif if (NULL == drawState.getRenderTarget()) { return false; } return true; }
static void update_degenerate_test(DegenerateTestData* data, const GrPoint& pt) { switch (data->fStage) { case DegenerateTestData::kInitial: data->fFirstPoint = pt; data->fStage = DegenerateTestData::kPoint; break; case DegenerateTestData::kPoint: if (pt.distanceToSqd(data->fFirstPoint) > kCloseSqd) { data->fLineNormal = pt - data->fFirstPoint; data->fLineNormal.normalize(); data->fLineNormal.setOrthog(data->fLineNormal); data->fLineC = -data->fLineNormal.dot(data->fFirstPoint); data->fStage = DegenerateTestData::kLine; } break; case DegenerateTestData::kLine: if (SkScalarAbs(data->fLineNormal.dot(pt) + data->fLineC) > kClose) { data->fStage = DegenerateTestData::kNonDegenerate; } case DegenerateTestData::kNonDegenerate: break; default: GrCrash("Unexpected degenerate test stage."); } }
GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu, kIsWrapped) { #ifndef SK_SCALAR_IS_FLOAT GrCrash("Assumes scalar is float."); #endif SkASSERT(!path.isEmpty()); GL_CALL_RET(fPathID, GenPaths(1)); SkSTArray<16, GrGLubyte, true> pathCommands; SkSTArray<16, SkPoint, true> pathPoints; int verbCnt = path.countVerbs(); int pointCnt = path.countPoints(); pathCommands.resize_back(verbCnt); pathPoints.resize_back(pointCnt); // TODO: Direct access to path points since we could pass them on directly. path.getPoints(&pathPoints[0], pointCnt); path.getVerbs(&pathCommands[0], verbCnt); GR_DEBUGCODE(int numPts = 0); for (int i = 0; i < verbCnt; ++i) { SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); pathCommands[i] = verb_to_gl_path_cmd(v); GR_DEBUGCODE(numPts += num_pts(v)); } GrAssert(pathPoints.count() == numPts); GL_CALL(PathCommands(fPathID, verbCnt, &pathCommands[0], 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); fBounds = path.getBounds(); }
void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty, const GrRect* conservativeBounds) { fList.reset(); int rectCount = 0; // compute bounds for common case of series of intersecting rects. bool isectRectValid = true; if (iter) { for (iter->rewind(); !iter->isDone(); iter->next()) { Element& e = fList.push_back(); e.fType = iter->getType(); e.fOp = iter->getOp(); // iterators should not emit replace GrAssert(kReplace_SetOp != e.fOp); switch (e.fType) { case kRect_ClipType: iter->getRect(&e.fRect); if (tx || ty) { e.fRect.offset(tx, ty); } ++rectCount; if (isectRectValid) { if (kIntersect_SetOp == e.fOp) { GrAssert(fList.count() <= 2); if (fList.count() > 1) { GrAssert(2 == rectCount); rectCount = 1; fList.pop_back(); GrAssert(kRect_ClipType == fList.back().fType); intersectWith(&fList.back().fRect, e.fRect); } } else { isectRectValid = false; } } break; case kPath_ClipType: e.fPath = *iter->getPath(); if (tx || ty) { e.fPath.offset(tx, ty); } e.fPathFill = iter->getPathFill(); isectRectValid = false; break; default: GrCrash("Unknown clip element type."); } } } fConservativeBoundsValid = false; if (isectRectValid && rectCount) { fConservativeBounds = fList[0].fRect; fConservativeBoundsValid = true; } else if (NULL != conservativeBounds) { fConservativeBounds = *conservativeBounds; fConservativeBoundsValid = true; } }
const char* GrGetGLSLVersionDecl(GrGLBinding binding, GrGLSLGeneration gen) { switch (gen) { case k110_GrGLSLGeneration: if (kES2_GrGLBinding == binding) { // ES2s shader language is based on version 1.20 but is version // 1.00 of the ES language. return "#version 100\n"; } else { GrAssert(kDesktop_GrGLBinding == binding); return "#version 110\n"; } case k130_GrGLSLGeneration: GrAssert(kDesktop_GrGLBinding == binding); return "#version 130\n"; case k140_GrGLSLGeneration: GrAssert(kDesktop_GrGLBinding == binding); return "#version 140\n"; case k150_GrGLSLGeneration: GrAssert(kDesktop_GrGLBinding == binding); return "#version 150\n"; default: GrCrash("Unknown GL version."); return ""; // suppress warning } }
bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { switch (feature) { case kFragCoordConventions_GLSLPrivateFeature: if (!fGpu->glCaps().fragCoordConventionsSupport()) { return false; } if (fGpu->glslGeneration() < k150_GrGLSLGeneration) { this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature, "GL_ARB_fragment_coord_conventions"); } return true; case kEXTShaderFramebufferFetch_GLSLPrivateFeature: if (GrGLCaps::kEXT_FBFetchType != fGpu->glCaps().fbFetchType()) { return false; } this->addFSFeature(1 << kEXTShaderFramebufferFetch_GLSLPrivateFeature, "GL_EXT_shader_framebuffer_fetch"); return true; case kNVShaderFramebufferFetch_GLSLPrivateFeature: if (GrGLCaps::kNV_FBFetchType != fGpu->glCaps().fbFetchType()) { return false; } this->addFSFeature(1 << kNVShaderFramebufferFetch_GLSLPrivateFeature, "GL_NV_shader_framebuffer_fetch"); return true; default: GrCrash("Unexpected GLSLPrivateFeature requested."); return false; } }
void GrGpuGLShaders::flushConvolution(int s) { const GrSamplerState& sampler = this->getDrawState().getSampler(s); int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni; if (GrGLProgram::kUnusedUniform != kernelUni) { GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(), sampler.getKernel())); } int imageIncrementUni = fProgramData->fUniLocations.fStages[s].fImageIncrementUni; if (GrGLProgram::kUnusedUniform != imageIncrementUni) { const GrGLTexture* texture = static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s)); float imageIncrement[2] = { 0 }; switch (sampler.getFilterDirection()) { case GrSamplerState::kX_FilterDirection: imageIncrement[0] = 1.0f / texture->width(); break; case GrSamplerState::kY_FilterDirection: imageIncrement[1] = 1.0f / texture->height(); break; default: GrCrash("Unknown filter direction."); } GL_CALL(Uniform2fv(imageIncrementUni, 1, imageIncrement)); } }
const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { if (NULL == fQuadIndexBuffer) { static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS; GrGpu* me = const_cast<GrGpu*>(this); fQuadIndexBuffer = me->createIndexBuffer(SIZE, false); if (NULL != fQuadIndexBuffer) { uint16_t* indices = (uint16_t*)fQuadIndexBuffer->lock(); if (NULL != indices) { fill_indices(indices, MAX_QUADS); fQuadIndexBuffer->unlock(); } else { indices = (uint16_t*)GrMalloc(SIZE); fill_indices(indices, MAX_QUADS); if (!fQuadIndexBuffer->updateData(indices, SIZE)) { fQuadIndexBuffer->unref(); fQuadIndexBuffer = NULL; GrCrash("Can't get indices into buffer!"); } GrFree(indices); } } } return fQuadIndexBuffer; }
GrIndexBuffer* GrAARectRenderer::aaFillRectIndexBuffer(GrGpu* gpu) { static const size_t kAAFillRectIndexBufferSize = kIndicesPerAAFillRect * sizeof(uint16_t) * kNumAAFillRectsInIndexBuffer; if (NULL == fAAFillRectIndexBuffer) { fAAFillRectIndexBuffer = gpu->createIndexBuffer(kAAFillRectIndexBufferSize, false); if (NULL != fAAFillRectIndexBuffer) { uint16_t* data = (uint16_t*) fAAFillRectIndexBuffer->lock(); bool useTempData = (NULL == data); if (useTempData) { data = SkNEW_ARRAY(uint16_t, kNumAAFillRectsInIndexBuffer * kIndicesPerAAFillRect); } for (int i = 0; i < kNumAAFillRectsInIndexBuffer; ++i) { // Each AA filled rect is drawn with 8 vertices and 10 triangles (8 around // the inner rect (for AA) and 2 for the inner rect. int baseIdx = i * kIndicesPerAAFillRect; uint16_t baseVert = (uint16_t)(i * kVertsPerAAFillRect); for (int j = 0; j < kIndicesPerAAFillRect; ++j) { data[baseIdx+j] = baseVert + gFillAARectIdx[j]; } } if (useTempData) { if (!fAAFillRectIndexBuffer->updateData(data, kAAFillRectIndexBufferSize)) { GrCrash("Can't get AA Fill Rect indices into buffer!"); } SkDELETE_ARRAY(data); } else { fAAFillRectIndexBuffer->unlock(); } } } return fAAFillRectIndexBuffer; }
void GrGLShaderBuilder::setupTextureAccess(const char* varyingFSName, GrSLType varyingType) { // FIXME: We don't know how the custom stage will manipulate the coords. So we give up on using // projective texturing and always give the stage 2D coords. This will be fixed when custom // stages are repsonsible for setting up their own tex coords / tex matrices. switch (varyingType) { case kVec2f_GrSLType: fDefaultTexCoordsName = varyingFSName; fTexCoordVaryingType = kVec2f_GrSLType; break; case kVec3f_GrSLType: { fDefaultTexCoordsName = "inCoord"; GrAssert(kNonStageIdx != fCurrentStage); fDefaultTexCoordsName.appendS32(fCurrentStage); fTexCoordVaryingType = kVec3f_GrSLType; fFSCode.appendf("\t%s %s = %s.xy / %s.z;\n", GrGLShaderVar::TypeString(kVec2f_GrSLType), fDefaultTexCoordsName.c_str(), varyingFSName, varyingFSName); break; } default: GrCrash("Tex coords must either be Vec2f or Vec3f"); } }
const GrVertexBuffer* GrGpu::getUnitSquareVertexBuffer() const { if (NULL == fUnitSquareVertexBuffer) { static const GrPoint DATA[] = { { 0, 0 }, { GR_Scalar1, 0 }, { GR_Scalar1, GR_Scalar1 }, { 0, GR_Scalar1 } #if 0 GrPoint(0, 0), GrPoint(GR_Scalar1,0), GrPoint(GR_Scalar1,GR_Scalar1), GrPoint(0, GR_Scalar1) #endif }; static const size_t SIZE = sizeof(DATA); GrGpu* me = const_cast<GrGpu*>(this); fUnitSquareVertexBuffer = me->createVertexBuffer(SIZE, false); if (NULL != fUnitSquareVertexBuffer) { if (!fUnitSquareVertexBuffer->updateData(DATA, SIZE)) { fUnitSquareVertexBuffer->unref(); fUnitSquareVertexBuffer = NULL; GrCrash("Can't get vertices into buffer!"); } } } return fUnitSquareVertexBuffer; }
void GrGpu::ConvertStencilFuncAndMask(GrStencilFunc func, bool clipInStencil, unsigned int clipBit, unsigned int userBits, unsigned int* ref, unsigned int* mask) { if (func < kBasicStencilFuncCount) { *mask &= userBits; *ref &= userBits; } else { if (clipInStencil) { switch (func) { case kAlwaysIfInClip_StencilFunc: *mask = clipBit; *ref = clipBit; break; case kEqualIfInClip_StencilFunc: case kLessIfInClip_StencilFunc: case kLEqualIfInClip_StencilFunc: *mask = (*mask & userBits) | clipBit; *ref = (*ref & userBits) | clipBit; break; case kNonZeroIfInClip_StencilFunc: *mask = (*mask & userBits) | clipBit; *ref = clipBit; break; default: GrCrash("Unknown stencil func"); } } else { *mask &= userBits; *ref &= userBits; } } }
void GrGLProgram::genInputColor(GrGLShaderBuilder* builder, SkString* inColor) { switch (fDesc.fColorInput) { case GrGLProgram::Desc::kAttribute_ColorInput: { builder->fVSAttrs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, COL_ATTR_NAME); const char *vsName, *fsName; builder->addVarying(kVec4f_GrSLType, "Color", &vsName, &fsName); builder->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName); *inColor = fsName; } break; case GrGLProgram::Desc::kUniform_ColorInput: { const char* name; fUniforms.fColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, kVec4f_GrSLType, "Color", &name); *inColor = name; break; } case GrGLProgram::Desc::kTransBlack_ColorInput: GrAssert(!"needComputedColor should be false."); break; case GrGLProgram::Desc::kSolidWhite_ColorInput: break; default: GrCrash("Unknown color type."); break; } }
GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenum pname, GrGLint* params) { switch (pname) { case GR_GL_BUFFER_MAPPED: { *params = GR_GL_FALSE; GrGLuint buf = 0; switch (target) { case GR_GL_ARRAY_BUFFER: buf = gCurrArrayBuffer; break; case GR_GL_ELEMENT_ARRAY_BUFFER: buf = gCurrElementArrayBuffer; break; } if (buf) { for (int i = 0; i < gMappedBuffers.count(); ++i) { if (gMappedBuffers[i] == buf) { *params = GR_GL_TRUE; break; } } } break; } default: GrCrash("Unexpected pname to GetBufferParamateriv"); break; } };
const char* GrGetGLSLVersionDecl(const GrGLContextInfo& info) { switch (info.glslGeneration()) { case k110_GrGLSLGeneration: if (kES_GrGLBinding == info.binding()) { // ES2s shader language is based on version 1.20 but is version // 1.00 of the ES language. return "#version 100\n"; } else { SkASSERT(kDesktop_GrGLBinding == info.binding()); return "#version 110\n"; } case k130_GrGLSLGeneration: SkASSERT(kDesktop_GrGLBinding == info.binding()); return "#version 130\n"; case k140_GrGLSLGeneration: SkASSERT(kDesktop_GrGLBinding == info.binding()); return "#version 140\n"; case k150_GrGLSLGeneration: SkASSERT(kDesktop_GrGLBinding == info.binding()); if (info.caps()->isCoreProfile()) { return "#version 150\n"; } else { return "#version 150 compatibility\n"; } default: GrCrash("Unknown GL version."); return ""; // suppress warning } }
GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetTexLevelParameteriv(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params) { // we used to use this to query stuff about externally created textures, // now we just require clients to tell us everything about the texture. GrCrash("Should never query texture parameters."); }
GrCacheID::Domain GrCacheID::GenerateDomain() { static int32_t gNextDomain = kInvalid_Domain + 1; int32_t domain = sk_atomic_inc(&gNextDomain); if (domain >= 1 << (8 * sizeof(Domain))) { GrCrash("Too many Cache Domains"); } return static_cast<Domain>(domain); }
// Queries on the null GL just don't do anything at all. We could potentially make // the timers work. GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetQueryiv(GrGLenum GLtarget, GrGLenum pname, GrGLint *params) { switch (pname) { case GR_GL_CURRENT_QUERY: *params = 0; break; case GR_GL_QUERY_COUNTER_BITS: *params = 32; break; default: GrCrash("Unexpected pname passed GetQueryiv."); } }
const GrGLubyte* GR_GL_FUNCTION_TYPE noOpGLGetStringi(GrGLenum name, GrGLuint i) { switch (name) { case GR_GL_EXTENSIONS: if (static_cast<size_t>(i) <= GR_ARRAY_COUNT(kExtensions)) { return (const GrGLubyte*) kExtensions[i]; } else { return NULL; } default: GrCrash("Unexpected name passed to GetStringi"); return NULL; } }
const GrGLubyte* GR_GL_FUNCTION_TYPE nullGLGetString(GrGLenum name) { switch (name) { case GR_GL_EXTENSIONS: return (const GrGLubyte*)"GL_ARB_framebuffer_object GL_ARB_blend_func_extended GL_ARB_timer_query GL_ARB_draw_buffers GL_ARB_occlusion_query GL_EXT_blend_color GL_EXT_stencil_wrap"; case GR_GL_VERSION: return (const GrGLubyte*)"4.0 Null GL"; case GR_GL_SHADING_LANGUAGE_VERSION: return (const GrGLubyte*)"4.20.8 Null GLSL"; default: GrCrash("Unexpected name to GetString"); return NULL; } }
bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, int width, int height, int dstRB, void* dst) { const SkGlyph& glyph = fStrike->getGlyphIDMetrics(GrGlyph::UnpackID(packed), GrGlyph::UnpackFixedX(packed), GrGlyph::UnpackFixedY(packed)); SkASSERT(glyph.fWidth == width); SkASSERT(glyph.fHeight == height); const void* src = fStrike->findImage(glyph); if (NULL == src) { return false; } int srcRB = glyph.rowBytes(); // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to // check the glyph's format, not the strike's format, and to be able to convert to any of the // GrMaskFormats. if (SkMask::kBW_Format == glyph.fMaskFormat) { // expand bits to our mask type const uint8_t* bits = reinterpret_cast<const uint8_t*>(src); switch (this->getMaskFormat()) { case kA8_GrMaskFormat: { uint8_t* bytes = reinterpret_cast<uint8_t*>(dst); expand_bits(bytes, bits, width, height, dstRB, srcRB); break; } case kA565_GrMaskFormat: { uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst); expand_bits(rgb565, bits, width, height, dstRB, srcRB); break; } case kA888_GrMaskFormat: { uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst); expand_bits(rgba8888, bits, width, height, dstRB, srcRB); break; } default: GrCrash("Invalid GrMaskFormat"); } } else if (srcRB == dstRB) { memcpy(dst, src, dstRB * height); } else { const int bbp = GrMaskFormatBytesPerPixel(this->getMaskFormat()); for (int y = 0; y < height; y++) { memcpy(dst, src, width * bbp); src = (const char*)src + srcRB; dst = (char*)dst + dstRB; } } return true; }
void GrInOrderDrawBuffer::onDrawNonIndexed(GrPrimitiveType primitiveType, int startVertex, int vertexCount) { if (!vertexCount) { return; } fCurrQuad = 0; GeometryPoolState& poolState = fGeoPoolStateStack.back(); Draw& draw = fDraws.push_back(); draw.fPrimitiveType = primitiveType; draw.fStartVertex = startVertex; draw.fStartIndex = 0; draw.fVertexCount = vertexCount; draw.fIndexCount = 0; draw.fClipChanged = this->needsNewClip(); if (draw.fClipChanged) { this->pushClip(); } draw.fStateChanged = this->needsNewState(); if (draw.fStateChanged) { this->pushState(); } draw.fVertexLayout = this->getGeomSrc().fVertexLayout; switch (this->getGeomSrc().fVertexSrc) { case kBuffer_GeometrySrcType: draw.fVertexBuffer = this->getGeomSrc().fVertexBuffer; break; case kReserved_GeometrySrcType: // fallthrough case kArray_GeometrySrcType: { size_t vertexBytes = (vertexCount + startVertex) * VertexSize(this->getGeomSrc().fVertexLayout); poolState.fUsedPoolVertexBytes = GrMax(poolState.fUsedPoolVertexBytes, vertexBytes); draw.fVertexBuffer = poolState.fPoolVertexBuffer; draw.fStartVertex += poolState.fPoolStartVertex; break; } default: GrCrash("unknown geom src type"); } draw.fVertexBuffer->ref(); draw.fIndexBuffer = NULL; }
// used for both the program and shader params GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetShaderOrProgramiv(GrGLuint program, GrGLenum pname, GrGLint* params) { switch (pname) { case GR_GL_LINK_STATUS: // fallthru case GR_GL_COMPILE_STATUS: *params = GR_GL_TRUE; break; case GR_GL_INFO_LOG_LENGTH: *params = 0; break; // we don't expect any other pnames default: GrCrash("Unexpected pname to GetProgramiv"); break; } }
GrPathFill SkGrClipIterator::getPathFill() const { switch (fCurr->fPath->getFillType()) { case SkPath::kWinding_FillType: return kWinding_PathFill; case SkPath::kEvenOdd_FillType: return kEvenOdd_PathFill; case SkPath::kInverseWinding_FillType: return kInverseWinding_PathFill; case SkPath::kInverseEvenOdd_FillType: return kInverseEvenOdd_PathFill; default: GrCrash("Unsupported path fill in clip."); return kWinding_PathFill; // suppress warning } }
void GrGpuGLShaders::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram.getDesc(); const GrDrawState& drawState = this->getDrawState(); if (this->getVertexLayout() & kColor_VertexLayoutBit) { // color will be specified per-vertex as an attribute // invalidate the const vertex attrib color fHWDrawState.setColor(GrColor_ILLEGAL); } else { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: if (fHWDrawState.getColor() != color) { // OpenGL ES only supports the float varieties of // glVertexAttrib float c[] = GR_COLOR_TO_VEC4(color); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); fHWDrawState.setColor(color); } break; case ProgramDesc::kUniform_ColorInput: if (fProgramData->fColor != color) { // OpenGL ES doesn't support unsigned byte varieties of // glUniform float c[] = GR_COLOR_TO_VEC4(color); GrAssert(GrGLProgram::kUnusedUniform != fProgramData->fUniLocations.fColorUni); GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorUni, 1, c)); fProgramData->fColor = color; } break; case ProgramDesc::kSolidWhite_ColorInput: case ProgramDesc::kTransBlack_ColorInput: break; default: GrCrash("Unknown color type."); } } if (fProgramData->fUniLocations.fColorFilterUni != GrGLProgram::kUnusedUniform && fProgramData->fColorFilterColor != drawState.getColorFilterColor()) { float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor()); GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c)); fProgramData->fColorFilterColor = drawState.getColorFilterColor(); } }
bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { switch (feature) { case kStandardDerivatives_GLSLFeature: if (!fGpu->glCaps().shaderDerivativeSupport()) { return false; } if (kES_GrGLBinding == fGpu->glBinding()) { this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, "GL_OES_standard_derivatives"); } return true; default: GrCrash("Unexpected GLSLFeature requested."); return false; } }
GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetIntegerv(GrGLenum pname, GrGLint* params) { switch (pname) { case GR_GL_STENCIL_BITS: *params = 8; break; case GR_GL_SAMPLES: *params = 1; break; case GR_GL_FRAMEBUFFER_BINDING: *params = 0; break; case GR_GL_VIEWPORT: params[0] = 0; params[1] = 0; params[2] = 800; params[3] = 600; break; case GR_GL_MAX_TEXTURE_IMAGE_UNITS: *params = 8; break; case GR_GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = 16; break; case GR_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = 16 * 4; break; case GR_GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = 0; break; case GR_GL_COMPRESSED_TEXTURE_FORMATS: break; case GR_GL_MAX_TEXTURE_SIZE: *params = 8192; break; case GR_GL_MAX_RENDERBUFFER_SIZE: *params = 8192; break; case GR_GL_MAX_SAMPLES: *params = 32; break; case GR_GL_MAX_VERTEX_ATTRIBS: *params = 16; break; default: GrCrash("Unexpected pname to GetIntegerv"); } }
void GrGpuGL::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram->getDesc(); const GrDrawState& drawState = this->getDrawState(); if (this->getVertexLayout() & GrDrawState::kColor_VertexLayoutBit) { // color will be specified per-vertex as an attribute // invalidate the const vertex attrib color fHWConstAttribColor = GrColor_ILLEGAL; } else { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: if (fHWConstAttribColor != color) { // OpenGL ES only supports the float varieties of glVertexAttrib GrGLfloat c[4]; GrColorToRGBAFloat(color, c); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); fHWConstAttribColor = color; } break; case ProgramDesc::kUniform_ColorInput: if (fCurrentProgram->fColor != color) { // OpenGL ES doesn't support unsigned byte varieties of glUniform GrGLfloat c[4]; GrColorToRGBAFloat(color, c); GrAssert(kInvalidUniformHandle != fCurrentProgram->fUniformHandles.fColorUni); fCurrentProgram->fUniformManager.set4fv( fCurrentProgram->fUniformHandles.fColorUni, 0, 1, c); fCurrentProgram->fColor = color; } break; case ProgramDesc::kSolidWhite_ColorInput: case ProgramDesc::kTransBlack_ColorInput: break; default: GrCrash("Unknown color type."); } } UniformHandle filterColorUni = fCurrentProgram->fUniformHandles.fColorFilterUni; if (kInvalidUniformHandle != filterColorUni && fCurrentProgram->fColorFilterColor != drawState.getColorFilterColor()) { GrGLfloat c[4]; GrColorToRGBAFloat(drawState.getColorFilterColor(), c); fCurrentProgram->fUniformManager.set4fv(filterColorUni, 0, 1, c); fCurrentProgram->fColorFilterColor = drawState.getColorFilterColor(); } }
void GrGLProgram::overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const { switch (fDesc.fDualSrcOutput) { case Desc::kNone_DualSrcOutput: break; // the prog will write a coverage value to the secondary // output and the dst is blended by one minus that value. case Desc::kCoverage_DualSrcOutput: case Desc::kCoverageISA_DualSrcOutput: case Desc::kCoverageISC_DualSrcOutput: *dstCoeff = (GrBlendCoeff)GrGpu::kIS2C_GrBlendCoeff; break; default: GrCrash("Unexpected dual source blend output"); break; } }