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"
96918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#include "GrGpuGL.h"
106918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
126918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X);
136918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
146918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLAttribArrayState::set(const GrGpuGL* gpu,
156918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               int index,
166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLVertexBuffer* buffer,
176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLint size,
186918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLenum type,
196918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLboolean normalized,
206918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLsizei stride,
216918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                               GrGLvoid* offset) {
22f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(index >= 0 && index < fAttribArrayStates.count());
236918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    AttribArrayState* array = &fAttribArrayStates[index];
246918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    if (!array->fEnableIsValid || !array->fEnabled) {
256918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        GR_GL_CALL(gpu->glInterface(), EnableVertexAttribArray(index));
266918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fEnableIsValid = true;
276918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fEnabled = true;
286918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
296918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    if (!array->fAttribPointerIsValid ||
306918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fVertexBufferID != buffer->bufferID() ||
316918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fSize != size ||
326918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fNormalized != normalized ||
336918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fStride != stride ||
346918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fOffset != offset) {
356918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
366918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        buffer->bind();
376918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        GR_GL_CALL(gpu->glInterface(), VertexAttribPointer(index,
386918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                                                           size,
396918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                                                           type,
406918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                                                           normalized,
416918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                                                           stride,
426918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                                                           offset));
436918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fAttribPointerIsValid = true;
446918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fVertexBufferID = buffer->bufferID();
456918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fSize = size;
466918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fNormalized = normalized;
476918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fStride = stride;
486918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        array->fOffset = offset;
496918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
506918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
516918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
526ebfbf9968c76b0238f1b48296ff1b507e110ba1commit-bot@chromium.orgvoid GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask) {
536918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    int count = fAttribArrayStates.count();
546918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    for (int i = 0; i < count; ++i) {
556918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        if (!(usedMask & 0x1)) {
566918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            if (!fAttribArrayStates[i].fEnableIsValid || fAttribArrayStates[i].fEnabled) {
576918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                GR_GL_CALL(gpu->glInterface(), DisableVertexAttribArray(i));
586918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                fAttribArrayStates[i].fEnableIsValid = true;
596918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com                fAttribArrayStates[i].fEnabled = false;
606918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            }
61ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org        } else {
62ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org            SkASSERT(fAttribArrayStates[i].fEnableIsValid && fAttribArrayStates[i].fEnabled);
636918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        }
646918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        // if the count is greater than 64 then this will become 0 and we will disable arrays 64+.
656918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        usedMask >>= 1;
666918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
676918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
686918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
696918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com///////////////////////////////////////////////////////////////////////////////////////////////////
706918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
716918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comGrGLVertexArray::GrGLVertexArray(GrGpuGL* gpu, GrGLint id, int attribCount)
72089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    : INHERITED(gpu, false)
736918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    , fID(id)
746918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    , fAttribArrays(attribCount)
756918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    , fIndexBufferIDIsValid(false) {
76169612621f00b3fe9f71014079991287d311751absalomon    this->registerWithCache();
776918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
786918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
796918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLVertexArray::onAbandon() {
806918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    fID = 0;
816918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    INHERITED::onAbandon();
826918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
836918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
846918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLVertexArray::onRelease() {
856918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    if (0 != fID) {
866918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        GL_CALL(DeleteVertexArrays(1, &fID));
876918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        GPUGL->notifyVertexArrayDelete(fID);
886918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        fID = 0;
896918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
906918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    INHERITED::onRelease();
916918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
926918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
936918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comGrGLAttribArrayState* GrGLVertexArray::bind() {
946918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    if (0 == fID) {
956918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        return NULL;
966918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
976918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    GPUGL->bindVertexArray(fID);
986918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    return &fAttribArrays;
996918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
100754a3eb73b796398062f09cc98eae224262a3bc8skia.committer@gmail.com
1016918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comGrGLAttribArrayState* GrGLVertexArray::bindWithIndexBuffer(const GrGLIndexBuffer* buffer) {
1026918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    GrGLAttribArrayState* state = this->bind();
10349f085dddff10473b6ebf832a974288300224e60bsalomon    if (state && buffer) {
1046918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        GrGLuint bufferID = buffer->bufferID();
1056918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        if (!fIndexBufferIDIsValid || bufferID != fIndexBufferID) {
1066918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, bufferID));
1076918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            fIndexBufferIDIsValid = true;
1086918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com            fIndexBufferID = bufferID;
1096918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        }
1106918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
1116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    return state;
1126918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
1136918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
1146918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLVertexArray::notifyIndexBufferDelete(GrGLuint bufferID) {
1156918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    if (fIndexBufferIDIsValid && bufferID == fIndexBufferID) {
1166918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com        fIndexBufferID = 0;
1176918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    }
1186918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com }
1196918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com
1206918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.comvoid GrGLVertexArray::invalidateCachedState() {
121ce6da4d96ae00a66c56c45a3b902224d8b3e6cf7commit-bot@chromium.org    fAttribArrays.invalidate();
1226918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com    fIndexBufferIDIsValid = false;
1236918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com}
124