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, ¤tFb); 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