13f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com/* 23f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com * Copyright 2013 Google Inc. 33f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com * 43f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 53f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com * found in the LICENSE file. 63f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com */ 73f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 83f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com#include "GrGLVertexArray.h" 93f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com#include "GrGpuGL.h" 103f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 113f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com#define GPUGL static_cast<GrGpuGL*>(this->getGpu()) 123f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X); 133f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 143f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comvoid GrGLAttribArrayState::set(const GrGpuGL* gpu, 153f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com int index, 163f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLVertexBuffer* buffer, 173f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLint size, 183f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLenum type, 193f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLboolean normalized, 203f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLsizei stride, 213f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLvoid* offset) { 22a91959e0e4997d3a73b38e6d7f0296c566a4b1d0tfarina@chromium.org SkASSERT(index >= 0 && index < fAttribArrayStates.count()); 233f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com AttribArrayState* array = &fAttribArrayStates[index]; 243f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (!array->fEnableIsValid || !array->fEnabled) { 253f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index)); 263f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fEnableIsValid = true; 273f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fEnabled = true; 283f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 293f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (!array->fAttribPointerIsValid || 303f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fVertexBufferID != buffer->bufferID() || 313f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fSize != size || 323f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fNormalized != normalized || 333f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fStride != stride || 343f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fOffset != offset) { 353f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 363f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com buffer->bind(); 373f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index, 383f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com size, 393f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com type, 403f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com normalized, 413f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com stride, 423f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com offset)); 433f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fAttribPointerIsValid = true; 443f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fVertexBufferID = buffer->bufferID(); 453f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fSize = size; 463f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fNormalized = normalized; 473f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fStride = stride; 483f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com array->fOffset = offset; 493f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 503f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 513f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 520f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.orgvoid GrGLAttribArrayState::setFixedFunctionVertexArray(const GrGpuGL* gpu, 530f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GrGLVertexBuffer* buffer, 540f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GrGLint size, 550f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GrGLenum type, 560f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GrGLsizei stride, 570f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GrGLvoid* offset) { 580f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org SkASSERT(gpu->glCaps().fixedFunctionSupport()); 590f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org AttribArrayState* array = &fFixedFunctionVertexArray; 600f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (!array->fEnableIsValid || !array->fEnabled) { 610f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), EnableClientState(GR_GL_VERTEX_ARRAY)); 620f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fEnableIsValid = true; 630f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fEnabled = true; 640f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 650f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (!array->fAttribPointerIsValid || 660f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fVertexBufferID != buffer->bufferID() || 670f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fSize != size || 680f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fStride != stride || 690f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fOffset != offset) { 700f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org 710f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org buffer->bind(); 720f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), VertexPointer(size, 730f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org type, 740f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org stride, 750f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org offset)); 760f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fAttribPointerIsValid = true; 770f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fVertexBufferID = buffer->bufferID(); 780f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fSize = size; 790f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fStride = stride; 800f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org array->fOffset = offset; 810f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 820f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org} 830f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org 840f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.orgvoid GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask, bool usingFFVertexArray) { 853f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com int count = fAttribArrayStates.count(); 863f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com for (int i = 0; i < count; ++i) { 873f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (!(usedMask & 0x1)) { 883f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) { 893f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i)); 903f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fAttribArrayStates[i].fEnableIsValid = true; 913f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fAttribArrayStates[i].fEnabled = false; 923f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 930f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } else { 940f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled); 953f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 963f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. 973f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com usedMask >>= 1; 983f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 990f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org 1000f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org // Deal with fixed-function vertex arrays. 1010f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (gpu->glCaps().fixedFunctionSupport()) { 1020f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (!usingFFVertexArray) { 1030f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (!fFixedFunctionVertexArray.fEnableIsValid || fFixedFunctionVertexArray.fEnabled) { 1040f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_VERTEX_ARRAY)); 1050f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org fFixedFunctionVertexArray.fEnableIsValid = true; 1060f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org fFixedFunctionVertexArray.fEnabled = false; 1070f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 1080f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } else { 1090f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org SkASSERT(fFixedFunctionVertexArray.fEnableIsValid && fFixedFunctionVertexArray.fEnabled); 1100f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 1110f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org // When we use fixed function vertex processing we always use the vertex array and none of 1120f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org // the other arrays. 1130f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org if (!fUnusedFixedFunctionArraysDisabled) { 1140f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_NORMAL_ARRAY)); 1150f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_COLOR_ARRAY)); 1160f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_SECONDARY_COLOR_ARRAY)); 1170f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_INDEX_ARRAY)); 1180f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_EDGE_FLAG_ARRAY)); 1190f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org for (int i = 0; i < gpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { 1200f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), ClientActiveTexture(GR_GL_TEXTURE0 + i)); 1210f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_TEXTURE_COORD_ARRAY)); 1220f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 1230f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org fUnusedFixedFunctionArraysDisabled = true; 1240f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 1250f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } else { 1260f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org SkASSERT(!usingFFVertexArray); 1270f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org } 1283f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 1293f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1303f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com/////////////////////////////////////////////////////////////////////////////////////////////////// 1313f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1323f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comGrGLVertexArray::GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount) 1333f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com : GrResource(gpu, false) 1343f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com , fID(id) 1353f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com , fAttribArrays(attribCount) 1363f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com , fIndexBufferIDIsValid(false) { 1373f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 1383f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1393f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comvoid GrGLVertexArray::onAbandon() { 1403f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fID = 0; 1413f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com INHERITED::onAbandon(); 1423f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 1433f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1443f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comvoid GrGLVertexArray::onRelease() { 1453f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (0 != fID) { 1463f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GL_CALL(DeleteVertexArrays(1, &fID)); 1473f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GPUGL->notifyVertexArrayDelete(fID); 1483f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fID = 0; 1493f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1503f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com INHERITED::onRelease(); 1513f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 1523f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1533f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comGrGLAttribArrayState* GrGLVertexArray::bind() { 1543f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (0 == fID) { 1553f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com return NULL; 1563f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1573f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GPUGL->bindVertexArray(fID); 1583f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com return &fAttribArrays; 1593f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 16029b3cce7ba96f4a35037be9373e5a69a57e86336skia.committer@gmail.com 1613f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comGrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) { 1623f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLAttribArrayState* state = this->bind(); 1633f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (NULL != state && NULL != buffer) { 1643f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GrGLuint bufferID = buffer->bufferID(); 1653f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) { 1663f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID)); 1673f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fIndexBufferIDIsValid = true; 1683f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fIndexBufferID = bufferID; 1693f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1703f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1713f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com return state; 1723f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 1733f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1743f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comvoid GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) { 1753f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) { 1763f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fIndexBufferID = 0; 1773f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1783f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com } 1793f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com 1803f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.comvoid GrGLVertexArray::invalidateCachedState() { 1810f1951e72a0b0670c5cbdb22920bb49f6abe3d21commit-bot@chromium.org fAttribArrays.invalidate(); 1823f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com fIndexBufferIDIsValid = false; 1833f177e9cbcd94d9fc9d969591cc939a81d16d111bsalomon@google.com} 184