void GrGLVertexBuffer::onRelease() { // make sure we've not been abandoned if (fBufferID) { GPUGL->notifyVertexBufferDelete(this); GL_CALL(DeleteBuffers(1, &fBufferID)); fBufferID = 0; } }
void GrGLRenderTarget::onRelease() { if (GrBackendObjectOwnership::kBorrowed != fRTFBOOwnership) { if (fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fTexFBOID)); } if (fRTFBOID && fRTFBOID != fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fRTFBOID)); } if (fMSColorRenderbufferID) { GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID)); } } fRTFBOID = 0; fTexFBOID = 0; fMSColorRenderbufferID = 0; INHERITED::onRelease(); }
/* Deletes the GL texture */ void Texture::deleteGLTex() { if (texName) { GL_CALL(glDeleteTextures(1, &texName));//Invalid operation? texName = 0; } }
void GrGLPathRendering::resetContext() { fHWProjectionMatrixState.invalidate(); // we don't use the model view matrix. GrGLenum matrixMode = fGpu->glStandard() == kGLES_GrGLStandard ? GR_GL_PATH_MODELVIEW : GR_GL_MODELVIEW; GL_CALL(MatrixLoadIdentity(matrixMode)); if (!caps().fragmentInputGenSupport) { for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); fHWPathTexGenSettings[i].fMode = GR_GL_NONE; fHWPathTexGenSettings[i].fNumComponents = 0; } fHWActivePathTexGenSets = 0; } fHWPathStencilSettings.invalidate(); }
void GrGLRenderTarget::onRelease() { if (kBorrowed_LifeCycle != fRTLifecycle) { if (fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fTexFBOID)); } if (fRTFBOID && fRTFBOID != fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fRTFBOID)); } if (fMSColorRenderbufferID) { GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID)); } } fRTFBOID = 0; fTexFBOID = 0; fMSColorRenderbufferID = 0; INHERITED::onRelease(); }
void GrGLPath::onRelease() { if (0 != fPathID && !this->isWrapped()) { GL_CALL(DeletePaths(fPathID, 1)); fPathID = 0; } INHERITED::onRelease(); }
void GrGLVertexArray::onRelease() { if (0 != fID) { GL_CALL(DeleteVertexArrays(1, &fID)); GPUGL->notifyVertexArrayDelete(fID); fID = 0; } INHERITED::onRelease(); }
void GrGpuGLShaders::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram.getDesc(); const GrDrawState& drawState = this->getDrawState(); if (this->getGeomSrc().fVertexLayout & 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 varities 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 only supports the float varities of glVertexAttrib 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(); } }
static void set_program(struct ctx *context, enum program_type type) { assert(context && type >= 0 && type < PROGRAM_LAST); context->program = &context->programs[type]; GL_CALL(glUseProgram(context->program->obj)); }
GrGLProgram::~GrGLProgram() { if (fProgramID) { GL_CALL(DeleteProgram(fProgramID)); } for (int i = 0; i < fFragmentProcessors.count(); ++i) { delete fFragmentProcessors[i]; } }
bool GrGLShaderBuilder::finish() { SkASSERT(0 == fOutput.fProgramID); GL_CALL_RET(fOutput.fProgramID, CreateProgram()); if (!fOutput.fProgramID) { return false; } SkTDArray<GrGLuint> shadersToDelete; if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) { GL_CALL(DeleteProgram(fOutput.fProgramID)); return false; } this->bindProgramLocations(fOutput.fProgramID); if (fUniformManager->isUsingBindUniform()) { fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); } GL_CALL(LinkProgram(fOutput.fProgramID)); // Calling GetProgramiv is expensive in Chromium. Assume success in release builds. bool checkLinked = !fGpu->ctxInfo().isChromium(); #ifdef SK_DEBUG checkLinked = true; #endif if (checkLinked) { GrGLint linked = GR_GL_INIT_ZERO; GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked)); if (!linked) { GrGLint infoLen = GR_GL_INIT_ZERO; GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen)); SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger if (infoLen > 0) { // retrieve length even though we don't need it to workaround // bug in chrome cmd buffer param validation. GrGLsizei length = GR_GL_INIT_ZERO; GL_CALL(GetProgramInfoLog(fOutput.fProgramID, infoLen+1, &length, (char*)log.get())); GrPrintf((char*)log.get()); } SkDEBUGFAIL("Error linking program"); GL_CALL(DeleteProgram(fOutput.fProgramID)); fOutput.fProgramID = 0; return false; } } if (!fUniformManager->isUsingBindUniform()) { fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms); } for (int i = 0; i < shadersToDelete.count(); ++i) { GL_CALL(DeleteShader(shadersToDelete[i])); } return true; }
void Mesh::UnSetAttributes(const Attribute *attributes) { for (;;) { switch (*attributes++) { case kPosition3f: GL_CALL(glDisableVertexAttribArray(kAttributePosition)); break; case kNormal3f: GL_CALL(glDisableVertexAttribArray(kAttributeNormal)); break; case kTangent4f: GL_CALL(glDisableVertexAttribArray(kAttributeTangent)); break; case kTexCoord2f: GL_CALL(glDisableVertexAttribArray(kAttributeTexCoord)); break; case kColor4ub: GL_CALL(glDisableVertexAttribArray(kAttributeColor)); break; case kBoneIndices4ub: GL_CALL(glDisableVertexAttribArray(kAttributeBoneIndices)); break; case kBoneWeights4ub: GL_CALL(glDisableVertexAttribArray(kAttributeBoneWeights)); break; case kEND: return; } } }
void GrGLUniformHandler::bindUniformLocations(GrGLuint programID, const GrGLCaps& caps) { if (caps.bindUniformLocationSupport()) { int count = fUniforms.count(); for (int i = 0; i < count; ++i) { GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str())); fUniforms[i].fLocation = i; } } }
void GrGLIndexBuffer::unlock() { GrAssert(fBufferID); GrAssert(isLocked()); GrAssert(this->getGpu()->getCaps().fBufferLockSupport); this->bind(); GL_CALL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER)); fLockPtr = NULL; }
void GrGLTexture::onRelease() { if (fInfo.fID) { if (GrBackendObjectOwnership::kBorrowed != fTextureIDOwnership) { GL_CALL(DeleteTextures(1, &fInfo.fID)); } fInfo.fID = 0; } INHERITED::onRelease(); }
GrGLProgram::~GrGLProgram() { if (fVShaderID) { GL_CALL(DeleteShader(fVShaderID)); } if (fGShaderID) { GL_CALL(DeleteShader(fGShaderID)); } if (fFShaderID) { GL_CALL(DeleteShader(fFShaderID)); } if (fProgramID) { GL_CALL(DeleteProgram(fProgramID)); } for (int i = 0; i < GrDrawState::kNumStages; ++i) { delete fProgramStage[i]; } }
void GrGLRenderTarget::onRelease() { if (!fIsWrapped) { if (fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fTexFBOID)); } if (fRTFBOID && fRTFBOID != fTexFBOID) { GL_CALL(DeleteFramebuffers(1, &fRTFBOID)); } if (fMSColorRenderbufferID) { GL_CALL(DeleteRenderbuffers(1, &fMSColorRenderbufferID)); } } fRTFBOID = 0; fTexFBOID = 0; fMSColorRenderbufferID = 0; fIsWrapped = false; INHERITED::onRelease(); }
void Mesh::Render(Renderer &renderer, bool ignore_material, size_t instances) { SetAttributes(vbo_, format_, static_cast<int>(vertex_size_), nullptr); for (auto it = indices_.begin(); it != indices_.end(); ++it) { if (!ignore_material) it->mat->Set(renderer); GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->ibo)); DrawElement(renderer, it->count, static_cast<int32_t>(instances)); } UnSetAttributes(format_); }
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { const GrPrimitiveProcessor& primProc = fProgramBuilder->primitiveProcessor(); int vaCount = primProc.numAttribs(); for (int i = 0; i < vaCount; i++) { GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName)); } return; }
void BufferObject::FreeBufferObject() { ASSERT(m_bufferId != 0); GL_CALL(glDeleteBuffers(1, &m_bufferId)); m_bufferId = 0; m_isDirty = false; m_sizeInBytes = 0; }
void Texture::Bind(TextureId textureHandle, GLuint _slotIndex) { GLHELPER_ASSERT(_slotIndex < sizeof(s_boundTextures) / sizeof(void*), "Can't bind texture to slot " + std::to_string(_slotIndex) + ". Maximum number of slots is " + std::to_string(sizeof(s_boundTextures) / sizeof(Texture*))); if(s_boundTextures[_slotIndex] != textureHandle) { GL_CALL(glBindTextureUnit, _slotIndex, textureHandle); s_boundTextures[_slotIndex] = textureHandle; } }
void GrGpuGLShaders::flushTextureMatrix(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni; GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (NULL != texture) { if (GrGLProgram::kUnusedUniform != uni && (((1 << s) & fDirtyFlags.fTextureChangedMask) || getHWSamplerMatrix(s) != getSamplerMatrix(s))) { GrAssert(NULL != fCurrDrawState.fTextures[s]); GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; GrMatrix m = getSamplerMatrix(s); GrSamplerState::SampleMode mode = fCurrDrawState.fSamplerStates[s].getSampleMode(); AdjustTextureMatrix(texture, mode, &m); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrGLfloat mt[] = { GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), GrScalarToFloat(m[GrMatrix::kMPersp0]), GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), GrScalarToFloat(m[GrMatrix::kMPersp1]), GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), GrScalarToFloat(m[GrMatrix::kMPersp2]) }; if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) { int baseIdx = GrGLProgram::TextureMatrixAttributeIdx(s); GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0)); GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3)); GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6)); } else { GL_CALL(UniformMatrix3fv(uni, 1, false, mt)); } recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } }
bool Buffer::unmap() { GL_ASSERT(_mapped, "unmapping buffer %p, which is not mapped", this); bool rv; BufferBindguard guard(_target, *this); GL_CALL(rv = glUnmapBuffer(_target)); if (rv) { _mapped = false; } return rv; }
void GLInstancedRendering::onResetGpuResources(ResetType resetType) { if (fVertexArrayID && ResetType::kDestroy == resetType) { GL_CALL(DeleteVertexArrays(1, &fVertexArrayID)); this->glGpu()->notifyVertexArrayDelete(fVertexArrayID); } fVertexArrayID = 0; fInstanceBuffer.reset(); fDrawIndirectBuffer.reset(); fInstanceAttribsBufferUniqueId = SK_InvalidUniqueID; }
bool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) { if (this->wasDestroyed()) { return false; } SkASSERT(!this->isMapped()); VALIDATE(); if (srcSizeInBytes > fSizeInBytes) { return false; } if (0 == fBufferID) { memcpy(fCPUData, src, srcSizeInBytes); return true; } SkASSERT(srcSizeInBytes <= fSizeInBytes); // bindbuffer handles dirty context GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this); #if GR_GL_USE_BUFFER_DATA_NULL_HINT if (fSizeInBytes == srcSizeInBytes) { GL_CALL(BufferData(target, (GrGLsizeiptr) srcSizeInBytes, src, fUsage)); } else { // Before we call glBufferSubData we give the driver a hint using // glBufferData with nullptr. This makes the old buffer contents // inaccessible to future draws. The GPU may still be processing // draws that reference the old contents. With this hint it can // assign a different allocation for the new contents to avoid // flushing the gpu past draws consuming the old contents. // TODO I think we actually want to try calling bufferData here GL_CALL(BufferData(target, fSizeInBytes, nullptr, fUsage)); GL_CALL(BufferSubData(target, 0, (GrGLsizeiptr) srcSizeInBytes, src)); } fGLSizeInBytes = fSizeInBytes; #else // Note that we're cheating on the size here. Currently no methods // allow a partial update that preserves contents of non-updated // portions of the buffer (map() does a glBufferData(..size, nullptr..)) GL_CALL(BufferData(target, srcSizeInBytes, src, fUsage)); fGLSizeInBytes = srcSizeInBytes; #endif VALIDATE(); return true; }
void GrGLBufferImpl::unlock(GrGpuGL* gpu) { VALIDATE(); SkASSERT(this->isLocked()); if (0 != fDesc.fID) { SkASSERT(gpu->caps()->bufferLockSupport()); this->bind(gpu); GL_CALL(gpu, UnmapBuffer(fBufferType)); } fLockPtr = NULL; }
GrGpuGLShaders::~GrGpuGLShaders() { if (fProgramData && 0 != fHWProgramID) { // detach the current program so there is no confusion on OpenGL's part // that we want it to be deleted SkASSERT(fHWProgramID == fProgramData->fProgramID); GL_CALL(UseProgram(0)); } delete fProgramCache; }
void GrGLProgram::initSamplerUniforms() { GL_CALL(UseProgram(fBuilderOutput.fProgramID)); GrGLint texUnitIdx = 0; if (fBuilderOutput.fUniformHandles.fDstCopySamplerUni.isValid()) { fUniformManager->setSampler(fBuilderOutput.fUniformHandles.fDstCopySamplerUni, texUnitIdx); fDstCopyTexUnit = texUnitIdx++; } fBuilderOutput.fColorEffects->initSamplers(*fUniformManager, &texUnitIdx); fBuilderOutput.fCoverageEffects->initSamplers(*fUniformManager, &texUnitIdx); }
void GrGLPathRendering::stencilPath(const GrPath* path, const GrStencilSettings& stencilSettings) { GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); this->flushPathStencilSettings(stencilSettings); SkASSERT(!fHWPathStencilSettings.isTwoSided()); const SkStrokeRec& stroke = path->getStroke(); GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { GL_CALL(StencilFillPath(id, fillMode, writeMask)); } if (stroke.needToApply()) { GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); } }
void GrGLVertexBuilder::bindVertexAttributes(GrGLuint programID) { const GrGeometryProcessor* gp = fProgramBuilder->fOptState.getGeometryProcessor(); const GrGeometryProcessor::VertexAttribArray& v = gp->getAttribs(); int vaCount = v.count(); for (int i = 0; i < vaCount; i++) { GL_CALL(BindAttribLocation(programID, i, v[i].fName)); } return; }