16918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com/* 26918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com * Copyright 2013 Google Inc. 36918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com * 46918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 56918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com * found in the LICENSE file. 66918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com */ 76918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 86918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#include "GrGLVertexArray.h" 9e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton#include "GrGLBuffer.h" 1039edf7664f50b6c890b933b5bbed67a8735b349bjvanverth#include "GrGLGpu.h" 116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 12793dc26ca6ba2543bf50e5215b858d1c265af50ccdaltonstruct AttribLayout { 13b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton bool fNormalized; // Only used by floating point types. 14b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton uint8_t fCount; 15b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton uint16_t fType; 16793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton}; 176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 18b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdaltonGR_STATIC_ASSERT(4 == sizeof(AttribLayout)); 19793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton 20b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdaltonstatic AttribLayout attrib_layout(GrVertexAttribType type) { 21b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton switch (type) { 22b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kFloat_GrVertexAttribType: 23b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 1, GR_GL_FLOAT}; 24b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec2f_GrVertexAttribType: 25b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 2, GR_GL_FLOAT}; 26b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec3f_GrVertexAttribType: 27b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 3, GR_GL_FLOAT}; 28b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec4f_GrVertexAttribType: 29b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 4, GR_GL_FLOAT}; 30b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec2i_GrVertexAttribType: 31b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 2, GR_GL_INT}; 32b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec3i_GrVertexAttribType: 33b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 3, GR_GL_INT}; 34b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec4i_GrVertexAttribType: 35b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 4, GR_GL_INT}; 36b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kUByte_GrVertexAttribType: 37b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {true, 1, GR_GL_UNSIGNED_BYTE}; 38b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec4ub_GrVertexAttribType: 39b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {true, 4, GR_GL_UNSIGNED_BYTE}; 40b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kVec2us_GrVertexAttribType: 41b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {true, 2, GR_GL_UNSIGNED_SHORT}; 42b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kInt_GrVertexAttribType: 43b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 1, GR_GL_INT}; 44b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton case kUint_GrVertexAttribType: 45b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 1, GR_GL_UNSIGNED_INT}; 46b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton } 47b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton SkFAIL("Unknown vertex attrib type"); 48b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton return {false, 0, 0}; 49b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton}; 506df86409ca586c3cb34f616f03501bd96181f9e4bsalomon 516df86409ca586c3cb34f616f03501bd96181f9e4bsalomonvoid GrGLAttribArrayState::set(GrGLGpu* gpu, 526918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com int index, 53485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrBuffer* vertexBuffer, 54793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton GrVertexAttribType type, 556918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLsizei stride, 566918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GrGLvoid* offset) { 57f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org SkASSERT(index >= 0 && index < fAttribArrayStates.count()); 586918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com AttribArrayState* array = &fAttribArrayStates[index]; 596918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (!array->fEnableIsValid || !array->fEnabled) { 606918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index)); 616918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com array->fEnableIsValid = true; 626918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com array->fEnabled = true; 636918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 648abb370aca280516f4861c6c942ec453aad018farobertphillips if (array->fVertexBufferUniqueID != vertexBuffer->uniqueID() || 65793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton array->fType != type || 666918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com array->fStride != stride || 676918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com array->fOffset != offset) { 68e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton gpu->bindBuffer(kVertex_GrBufferType, vertexBuffer); 69b37cb236c3a698b45a7d0deca0df32bb70bbaaa6csmartdalton const AttribLayout& layout = attrib_layout(type); 70793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton if (!GrVertexAttribTypeIsIntType(type)) { 71793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, 72793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton layout.fCount, 73793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton layout.fType, 74793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton layout.fNormalized, 75793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton stride, 76793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton offset)); 77793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton } else { 78793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton SkASSERT(gpu->caps()->shaderCaps()->integerSupport()); 79793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton SkASSERT(!layout.fNormalized); 80793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton GR_GL_CALL(gpu->glInterface(), VertexAttribIPointer(index, 81793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton layout.fCount, 82793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton layout.fType, 83793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton stride, 84793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton offset)); 85793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton } 868abb370aca280516f4861c6c942ec453aad018farobertphillips array->fVertexBufferUniqueID = vertexBuffer->uniqueID(); 87793dc26ca6ba2543bf50e5215b858d1c265af50ccdalton array->fType = type; 88c4d196c9c87f226eb33b8091dc50053c45c4e752dcheng array->fStride = stride; 896918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com array->fOffset = offset; 906918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 916918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 926918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 93861e1037017bbb7ac52ec5ebecab3a636a82a3e8bsalomonvoid GrGLAttribArrayState::disableUnusedArrays(const GrGLGpu* gpu, uint64_t usedMask) { 946918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com int count = fAttribArrayStates.count(); 956918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com for (int i = 0; i < count; ++i) { 966918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (!(usedMask & 0x1)) { 976918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { 986918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); 996918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com fAttribArrayStates[i].fEnableIsValid = true; 1006918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com fAttribArrayStates[i].fEnabled = false; 1016918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 102ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org } else { 103ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); 1046918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 1056918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. 1066918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com usedMask >>= 1; 1076918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 1086918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 1096918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 1106918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 1116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 1128780bc65bd5a53a38ac4b0a53a5fb283e066ec40bsalomonGrGLVertexArray::GrGLVertexArray(GrGLint id, int attribCount) 1138780bc65bd5a53a38ac4b0a53a5fb283e066ec40bsalomon : fID(id) 1146918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com , fAttribArrays(attribCount) 115e2e71c2df4e72e897bbe745752be0444aee5c29fcdalton , fIndexBufferUniqueID(SK_InvalidUniqueID) { 1166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 1176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 1188780bc65bd5a53a38ac4b0a53a5fb283e066ec40bsalomonGrGLAttribArrayState* GrGLVertexArray::bind(GrGLGpu* gpu) { 1196918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com if (0 == fID) { 12096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1216918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 1228780bc65bd5a53a38ac4b0a53a5fb283e066ec40bsalomon gpu->bindVertexArray(fID); 1236918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com return &fAttribArrays; 1246918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 125754a3eb73b796398062f09cc98eae224262a3bc8skia.committer@gmail.com 126485a12003ab48b54965d6f7172f3183358919d8ecsmartdaltonGrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(GrGLGpu* gpu, const GrBuffer* ibuff) { 1278780bc65bd5a53a38ac4b0a53a5fb283e066ec40bsalomon GrGLAttribArrayState* state = this->bind(gpu); 1288abb370aca280516f4861c6c942ec453aad018farobertphillips if (state && fIndexBufferUniqueID != ibuff->uniqueID()) { 129485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton if (ibuff->isCPUBacked()) { 130485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 0)); 131485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton } else { 132485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton const GrGLBuffer* glBuffer = static_cast<const GrGLBuffer*>(ibuff); 133485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton GR_GL_CALL(gpu->glInterface(), BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, 134485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton glBuffer->bufferID())); 135485a12003ab48b54965d6f7172f3183358919d8ecsmartdalton } 1368abb370aca280516f4861c6c942ec453aad018farobertphillips fIndexBufferUniqueID = ibuff->uniqueID(); 1376918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com } 1386918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com return state; 1396918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 1406918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com 1416918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLVertexArray::invalidateCachedState() { 142ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org fAttribArrays.invalidate(); 143294870ff119b89fc902773643b054f14e5d1f554Robert Phillips fIndexBufferUniqueID.makeInvalid(); 1446918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com} 145