10469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/*
20469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Copyright 2011, The Android Open Source Project
30469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
40469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Licensed under the Apache License, Version 2.0 (the "License");
50469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * you may not use this file except in compliance with the License.
60469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * You may obtain a copy of the License at
70469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
80469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *     http://www.apache.org/licenses/LICENSE-2.0
90469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy *
100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * Unless required by applicable law or agreed to in writing, software
110469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * distributed under the License is distributed on an "AS IS" BASIS,
120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * See the License for the specific language governing permissions and
140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy * limitations under the License.
150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy */
160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <pthread.h>
1893a826f78f6313db791e6fc880439189897651b3Siva Velusamy#include <cutils/log.h>
190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyextern "C" {
210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "liblzf/lzf.h"
220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_context.h"
250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android {
270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace {
280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyusing ::android::gl_hooks_t;
300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystatic pthread_key_t sTLSKey = -1;
320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystatic pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid createTLSKey() {
354e620ddce344e946ced992f61a69c367ff92fe24Mathias Agopian    pthread_key_create(&sTLSKey, (void (*)(void*))&releaseContext);
360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
370469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
380469dd6d55fa331bfd7de9431da98b6340d82271Siva VelusamyGLTraceContext *getGLTraceContext() {
390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    return (GLTraceContext*) pthread_getspecific(sTLSKey);
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid setGLTraceContext(GLTraceContext *c) {
430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    pthread_setspecific(sTLSKey, c);
440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
4693a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid setupTraceContextThreadSpecific(GLTraceContext *context) {
470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    pthread_once(&sPthreadOnceKey, createTLSKey);
480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    setGLTraceContext(context);
490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid releaseContext() {
520469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLTraceContext *c = getGLTraceContext();
530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (c != NULL) {
540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        delete c;
550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        setGLTraceContext(NULL);
560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
5993a826f78f6313db791e6fc880439189897651b3Siva VelusamyGLTraceState::GLTraceState(TCPStream *stream) {
6093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mTraceContextIds = 0;
6193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mStream = stream;
623f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
633f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    mCollectFbOnEglSwap = false;
643f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    mCollectFbOnGlDraw = false;
653f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    mCollectTextureDataOnGlTexImage = false;
663f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    pthread_rwlock_init(&mTraceOptionsRwLock, NULL);
6793a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
6893a826f78f6313db791e6fc880439189897651b3Siva Velusamy
6993a826f78f6313db791e6fc880439189897651b3Siva VelusamyGLTraceState::~GLTraceState() {
7093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (mStream) {
7193a826f78f6313db791e6fc880439189897651b3Siva Velusamy        mStream->closeStream();
7293a826f78f6313db791e6fc880439189897651b3Siva Velusamy        mStream = NULL;
7393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    }
7493a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
7593a826f78f6313db791e6fc880439189897651b3Siva Velusamy
7693a826f78f6313db791e6fc880439189897651b3Siva VelusamyTCPStream *GLTraceState::getStream() {
7793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return mStream;
7893a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
7993a826f78f6313db791e6fc880439189897651b3Siva Velusamy
803f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamyvoid GLTraceState::safeSetValue(bool *ptr, bool value, pthread_rwlock_t *lock) {
813f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    pthread_rwlock_wrlock(lock);
823f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    *ptr = value;
833f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    pthread_rwlock_unlock(lock);
843f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
853f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
863f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamybool GLTraceState::safeGetValue(bool *ptr, pthread_rwlock_t *lock) {
873f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    pthread_rwlock_rdlock(lock);
883f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    bool value = *ptr;
893f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    pthread_rwlock_unlock(lock);
903f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    return value;
913f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
923f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
933f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamyvoid GLTraceState::setCollectFbOnEglSwap(bool en) {
943f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    safeSetValue(&mCollectFbOnEglSwap, en, &mTraceOptionsRwLock);
953f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
963f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
973f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamyvoid GLTraceState::setCollectFbOnGlDraw(bool en) {
983f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    safeSetValue(&mCollectFbOnGlDraw, en, &mTraceOptionsRwLock);
993f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1003f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
1013f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamyvoid GLTraceState::setCollectTextureDataOnGlTexImage(bool en) {
1023f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    safeSetValue(&mCollectTextureDataOnGlTexImage, en, &mTraceOptionsRwLock);
1033f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1043f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
1053f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamybool GLTraceState::shouldCollectFbOnEglSwap() {
1063f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    return safeGetValue(&mCollectFbOnEglSwap, &mTraceOptionsRwLock);
1073f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1083f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
1093f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamybool GLTraceState::shouldCollectFbOnGlDraw() {
1103f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    return safeGetValue(&mCollectFbOnGlDraw, &mTraceOptionsRwLock);
1113f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1123f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
1133f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamybool GLTraceState::shouldCollectTextureDataOnGlTexImage() {
1143f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    return safeGetValue(&mCollectTextureDataOnGlTexImage, &mTraceOptionsRwLock);
1153f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1163f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
11793a826f78f6313db791e6fc880439189897651b3Siva VelusamyGLTraceContext *GLTraceState::createTraceContext(int version, EGLContext eglContext) {
11893a826f78f6313db791e6fc880439189897651b3Siva Velusamy    int id = __sync_fetch_and_add(&mTraceContextIds, 1);
11993a826f78f6313db791e6fc880439189897651b3Siva Velusamy
12093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    const size_t DEFAULT_BUFFER_SIZE = 8192;
12193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    BufferedOutputStream *stream = new BufferedOutputStream(mStream, DEFAULT_BUFFER_SIZE);
1223ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    GLTraceContext *traceContext = new GLTraceContext(id, version, this, stream);
12393a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mPerContextState[eglContext] = traceContext;
12493a826f78f6313db791e6fc880439189897651b3Siva Velusamy
12593a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return traceContext;
12693a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
12793a826f78f6313db791e6fc880439189897651b3Siva Velusamy
12893a826f78f6313db791e6fc880439189897651b3Siva VelusamyGLTraceContext *GLTraceState::getTraceContext(EGLContext c) {
12993a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return mPerContextState[c];
13093a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
13193a826f78f6313db791e6fc880439189897651b3Siva Velusamy
1323ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva VelusamyGLTraceContext::GLTraceContext(int id, int version, GLTraceState *state,
1333ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy        BufferedOutputStream *stream) :
13450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mId(id),
1353ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    mVersion(version),
13650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mState(state),
13750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mBufferedOutputStream(stream),
13850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mElementArrayBuffers(DefaultKeyedVector<GLuint, ElementArrayBuffer*>(NULL))
13950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy{
1400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontents = fbcompressed = NULL;
1410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontentsSize = 0;
14293a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
14393a826f78f6313db791e6fc880439189897651b3Siva Velusamy
14493a826f78f6313db791e6fc880439189897651b3Siva Velusamyint GLTraceContext::getId() {
14593a826f78f6313db791e6fc880439189897651b3Siva Velusamy    return mId;
1460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1483ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamyint GLTraceContext::getVersion() {
1493ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy    return mVersion;
1503ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy}
1513ef9e9671c224af82d2efec1a1e9a275fb9acf44Siva Velusamy
1523f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva VelusamyGLTraceState *GLTraceContext::getGlobalTraceState() {
1533f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy    return mState;
1543f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy}
1553f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy
1560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTraceContext::resizeFBMemory(unsigned minSize) {
1570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (fbcontentsSize >= minSize) {
1580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return;
1590469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (fbcontents != NULL) {
1620469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        free(fbcontents);
1630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        free(fbcompressed);
1640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
1650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontents = malloc(minSize);
1670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcompressed = malloc(minSize);
1680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontentsSize = minSize;
1700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/** obtain a pointer to the compressed framebuffer image */
1730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTraceContext::getCompressedFB(void **fb, unsigned *fbsize, unsigned *fbwidth,
174f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy                            unsigned *fbheight, FBBinding fbToRead) {
1750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int viewport[4] = {};
1760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
1770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    unsigned fbContentsSize = viewport[2] * viewport[3] * 4;
1780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    resizeFBMemory(fbContentsSize);
1800469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
181f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    // switch current framebuffer binding if necessary
182f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    GLint currentFb = -1;
183f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    bool fbSwitched = false;
184f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    if (fbToRead != CURRENTLY_BOUND_FB) {
185f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        hooks->gl.glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFb);
186f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
187f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        if (currentFb != 0) {
188f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy            hooks->gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
189f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy            fbSwitched = true;
190f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        }
191f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    }
192f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
1930469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    hooks->gl.glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
1940469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                        GL_RGBA, GL_UNSIGNED_BYTE, fbcontents);
195f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
196f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    // switch back to previously bound buffer if necessary
197f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    if (fbSwitched) {
198f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        hooks->gl.glBindFramebuffer(GL_FRAMEBUFFER, currentFb);
199f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    }
200f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
2010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbsize = lzf_compress(fbcontents, fbContentsSize, fbcompressed, fbContentsSize);
2020469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fb = fbcompressed;
2030469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbwidth = viewport[2];
2040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbheight = viewport[3];
2050469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
2060469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
20793a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTraceContext::traceGLMessage(GLMessage *msg) {
20893a826f78f6313db791e6fc880439189897651b3Siva Velusamy    mBufferedOutputStream->send(msg);
20993a826f78f6313db791e6fc880439189897651b3Siva Velusamy
21093a826f78f6313db791e6fc880439189897651b3Siva Velusamy    GLMessage_Function func = msg->function();
21193a826f78f6313db791e6fc880439189897651b3Siva Velusamy    if (func == GLMessage::eglSwapBuffers
212ad9693f4f0586d18a82fdbb70c6a89e43d662ff1Siva Velusamy        || func == GLMessage::eglCreateContext
213ad9693f4f0586d18a82fdbb70c6a89e43d662ff1Siva Velusamy        || func == GLMessage::eglMakeCurrent
21493a826f78f6313db791e6fc880439189897651b3Siva Velusamy        || func == GLMessage::glDrawArrays
21593a826f78f6313db791e6fc880439189897651b3Siva Velusamy        || func == GLMessage::glDrawElements) {
21693a826f78f6313db791e6fc880439189897651b3Siva Velusamy        mBufferedOutputStream->flush();
21793a826f78f6313db791e6fc880439189897651b3Siva Velusamy    }
21893a826f78f6313db791e6fc880439189897651b3Siva Velusamy}
21993a826f78f6313db791e6fc880439189897651b3Siva Velusamy
22050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid GLTraceContext::bindBuffer(GLuint bufferId, GLvoid *data, GLsizeiptr size) {
22150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    // free previously bound buffer if any
22250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    ElementArrayBuffer *oldBuffer = mElementArrayBuffers.valueFor(bufferId);
22350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (oldBuffer != NULL) {
22450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        delete oldBuffer;
22550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
22650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
22750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mElementArrayBuffers.add(bufferId, new ElementArrayBuffer(data, size));
22850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
22950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
23050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid GLTraceContext::getBuffer(GLuint bufferId, GLvoid **data, GLsizeiptr *size) {
23150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
23250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (buffer == NULL) {
23350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        *data = NULL;
23450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        *size = 0;
23550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    } else {
23650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        *data = buffer->getBuffer();
23750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        *size = buffer->getSize();
23850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
23950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
24050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
24150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid GLTraceContext::updateBufferSubData(GLuint bufferId, GLintptr offset, GLvoid *data,
24250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy                                                            GLsizeiptr size) {
24350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
24450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (buffer != NULL) {
24550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        buffer->updateSubBuffer(offset, data, size);
24650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
24750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
24850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
24950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid GLTraceContext::deleteBuffer(GLuint bufferId) {
25050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    ElementArrayBuffer *buffer = mElementArrayBuffers.valueFor(bufferId);
25150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (buffer != NULL) {
25250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        delete buffer;
25350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        mElementArrayBuffers.removeItem(bufferId);
25450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
25550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
25650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
25750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyElementArrayBuffer::ElementArrayBuffer(GLvoid *buf, GLsizeiptr size) {
25850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mBuf = malloc(size);
25950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mSize = size;
26050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
26150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (buf != NULL) {
26250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        memcpy(mBuf, buf, size);
26350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
26450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
26550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
26650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyElementArrayBuffer::~ElementArrayBuffer() {
26750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (mBuf != NULL) {
26850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        free(mBuf);
26950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        mSize = 0;
27050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
27150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
27250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    mBuf = NULL;
27350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
27450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
27550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamyvoid ElementArrayBuffer::updateSubBuffer(GLintptr offset, const GLvoid* data, GLsizeiptr size) {
27650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    if (offset + size <= mSize) {
27750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy        memcpy((char*)mBuf + offset, data, size);
27850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    }
27950129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
28050129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
28150129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLvoid *ElementArrayBuffer::getBuffer() {
28250129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return mBuf;
28350129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
28450129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
28550129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva VelusamyGLsizeiptr ElementArrayBuffer::getSize() {
28650129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy    return mSize;
28750129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy}
28850129e4ae2777dfbe0738f0f69b17f4d8f9400e2Siva Velusamy
2890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace gltrace
2900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace android
291