gltrace_context.cpp revision f132ac35d82a2960542619fb3fb91d22ab256dc7
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>
180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyextern "C" {
200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "liblzf/lzf.h"
210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_context.h"
240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android {
260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace gltrace {
270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyusing ::android::gl_hooks_t;
290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystatic pthread_key_t sTLSKey = -1;
310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamystatic pthread_once_t sPthreadOnceKey = PTHREAD_ONCE_INIT;
320469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
330469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid createTLSKey() {
340469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    pthread_key_create(&sTLSKey, NULL);
350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
360469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
370469dd6d55fa331bfd7de9431da98b6340d82271Siva VelusamyGLTraceContext *getGLTraceContext() {
380469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    return (GLTraceContext*) pthread_getspecific(sTLSKey);
390469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
400469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
410469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid setGLTraceContext(GLTraceContext *c) {
420469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    pthread_setspecific(sTLSKey, c);
430469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
440469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
450469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid initContext(unsigned version, gl_hooks_t *hooks) {
460469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    pthread_once(&sPthreadOnceKey, createTLSKey);
470469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLTraceContext *context = new GLTraceContext();
490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    context->hooks = hooks;
500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
510469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    setGLTraceContext(context);
520469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid releaseContext() {
550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    GLTraceContext *c = getGLTraceContext();
560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (c != NULL) {
570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        delete c;
580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        setGLTraceContext(NULL);
590469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
620469dd6d55fa331bfd7de9431da98b6340d82271Siva VelusamyGLTraceContext::GLTraceContext() {
630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontents = fbcompressed = NULL;
640469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontentsSize = 0;
650469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
660469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
670469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTraceContext::resizeFBMemory(unsigned minSize) {
680469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (fbcontentsSize >= minSize) {
690469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        return;
700469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
710469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
720469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    if (fbcontents != NULL) {
730469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        free(fbcontents);
740469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy        free(fbcompressed);
750469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    }
760469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
770469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontents = malloc(minSize);
780469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcompressed = malloc(minSize);
790469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
800469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    fbcontentsSize = minSize;
810469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
820469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
830469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy/** obtain a pointer to the compressed framebuffer image */
840469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTraceContext::getCompressedFB(void **fb, unsigned *fbsize, unsigned *fbwidth,
85f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy                            unsigned *fbheight, FBBinding fbToRead) {
860469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    int viewport[4] = {};
870469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
880469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    unsigned fbContentsSize = viewport[2] * viewport[3] * 4;
890469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
900469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    resizeFBMemory(fbContentsSize);
910469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
92f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    // switch current framebuffer binding if necessary
93f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    GLint currentFb = -1;
94f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    bool fbSwitched = false;
95f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    if (fbToRead != CURRENTLY_BOUND_FB) {
96f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        hooks->gl.glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFb);
97f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
98f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        if (currentFb != 0) {
99f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy            hooks->gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
100f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy            fbSwitched = true;
101f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        }
102f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    }
103f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
1040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    hooks->gl.glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
1050469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy                                        GL_RGBA, GL_UNSIGNED_BYTE, fbcontents);
106f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
107f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    // switch back to previously bound buffer if necessary
108f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    if (fbSwitched) {
109f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy        hooks->gl.glBindFramebuffer(GL_FRAMEBUFFER, currentFb);
110f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy    }
111f132ac35d82a2960542619fb3fb91d22ab256dc7Siva Velusamy
1120469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbsize = lzf_compress(fbcontents, fbContentsSize, fbcompressed, fbContentsSize);
1130469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fb = fbcompressed;
1140469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbwidth = viewport[2];
1150469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy    *fbheight = viewport[3];
1160469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}
1170469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy
1180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace gltrace
1190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy}; // namespace android
120