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 173f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy#include <arpa/inet.h> 180469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <stdlib.h> 190469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <cutils/log.h> 200469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include <cutils/properties.h> 210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 220469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "hooks.h" 230469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "glestrace.h" 240469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_context.h" 260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_egl.h" 270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_hooks.h" 280469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy#include "gltrace_transport.h" 290469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamynamespace android { 310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 3293a826f78f6313db791e6fc880439189897651b3Siva Velusamyusing gltrace::GLTraceState; 3393a826f78f6313db791e6fc880439189897651b3Siva Velusamyusing gltrace::GLTraceContext; 3493a826f78f6313db791e6fc880439189897651b3Siva Velusamyusing gltrace::TCPStream; 350469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 36a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamystatic pthread_mutex_t sGlTraceStateLock = PTHREAD_MUTEX_INITIALIZER; 37a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 38a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamystatic int sGlTraceInProgress; 3993a826f78f6313db791e6fc880439189897651b3Siva Velusamystatic GLTraceState *sGLTraceState; 403f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamystatic pthread_t sReceiveThreadId; 413f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 423f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy/** 433f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy * Task that monitors the control stream from the host and updates 443f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy * the trace status according to commands received from the host. 453f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy */ 463f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamystatic void *commandReceiveTask(void *arg) { 473f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy GLTraceState *state = (GLTraceState *)arg; 483f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy TCPStream *stream = state->getStream(); 493f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 502fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // The control stream always receives an integer size of the 512fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // command buffer, followed by the actual command buffer. 522fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmdSize; 532fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 542fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // Command Buffer 552fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy void *cmdBuf = NULL; 562fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmdBufSize = 0; 572fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 583f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy enum TraceSettingsMasks { 593f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_FB_ON_EGLSWAP_MASK = 1 << 0, 603f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_FB_ON_GLDRAW_MASK = 1 << 1, 613f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK = 1 << 2, 623f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy }; 633f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 643f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy while (true) { 652fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // read command size 662fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (stream->receive(&cmdSize, sizeof(uint32_t)) < 0) { 673f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy break; 683f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy } 692fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdSize = ntohl(cmdSize); 702fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 712fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // ensure command buffer is of required size 722fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdBufSize < cmdSize) { 732fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy free(cmdBuf); 742fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdBufSize = cmdSize; 752fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdBuf = malloc(cmdSize); 762fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdBuf == NULL) 772fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy break; 782fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 793f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 802fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // receive the command 812fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (stream->receive(cmdBuf, cmdSize) < 0) { 822fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy break; 832fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 842fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 852fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdSize != sizeof(uint32_t)) { 862fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // Currently, we only support commands that are a single integer, 872fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // so we skip all other commands 882fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy continue; 892fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 902fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 912fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmd = ntohl(*(uint32_t*)cmdBuf); 923f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 933f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0; 943f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0; 953f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectTextureData = (cmd & READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK) != 0; 963f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 973f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectFbOnEglSwap(collectFbOnEglSwap); 983f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectFbOnGlDraw(collectFbOnGlDraw); 993f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectTextureDataOnGlTexImage(collectTextureData); 1003f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 1013f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy ALOGD("trace options: eglswap: %d, gldraw: %d, texImage: %d", 1023f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData); 1033f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy } 1043f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 1052fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy ALOGE("Stopping OpenGL Trace Command Receiver\n"); 1062fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 1072fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy free(cmdBuf); 1083f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy return NULL; 1093f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy} 1100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 111a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy/** 112a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy * Starts Trace Server and waits for connection from the host. 113a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy * Returns -1 in case of connection error, 0 otherwise. 114a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy */ 115a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamyint GLTrace_start() { 116a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy int status = 0; 117a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy int clientSocket = -1; 118a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy TCPStream *stream = NULL; 119a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 120a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_lock(&sGlTraceStateLock); 1210469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 122a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (sGlTraceInProgress) { 123a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy goto done; 124a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy } 125a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 126a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy char udsName[PROPERTY_VALUE_MAX]; 1270832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy property_get("debug.egl.debug_portname", udsName, "gltrace"); 128a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy clientSocket = gltrace::acceptClientConnection(udsName); 12993a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (clientSocket < 0) { 130a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy ALOGE("Error creating GLTrace server socket. Tracing disabled."); 131a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy status = -1; 132a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy goto done; 13393a826f78f6313db791e6fc880439189897651b3Siva Velusamy } 13493a826f78f6313db791e6fc880439189897651b3Siva Velusamy 135a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy sGlTraceInProgress = 1; 136a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 13793a826f78f6313db791e6fc880439189897651b3Siva Velusamy // create communication channel to the host 138a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy stream = new TCPStream(clientSocket); 13993a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14093a826f78f6313db791e6fc880439189897651b3Siva Velusamy // initialize tracing state 14193a826f78f6313db791e6fc880439189897651b3Siva Velusamy sGLTraceState = new GLTraceState(stream); 1423f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 1433f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy pthread_create(&sReceiveThreadId, NULL, commandReceiveTask, sGLTraceState); 144a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 145a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamydone: 146a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_unlock(&sGlTraceStateLock); 147a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy return status; 1480469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1490469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1500469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTrace_stop() { 151a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_lock(&sGlTraceStateLock); 152a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 153a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (sGlTraceInProgress) { 154a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy sGlTraceInProgress = 0; 155a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy delete sGLTraceState; 156a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy sGLTraceState = NULL; 157a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy } 158a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 159a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_unlock(&sGlTraceStateLock); 1600469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1610469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 16293a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglCreateContext(int version, EGLContext c) { 163a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_lock(&sGlTraceStateLock); 164a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy GLTraceState *state = sGLTraceState; 165a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_unlock(&sGlTraceStateLock); 166a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 167a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (state == NULL) return; 168a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 16993a826f78f6313db791e6fc880439189897651b3Siva Velusamy // update trace state for new EGL context 170a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy GLTraceContext *traceContext = state->createTraceContext(version, c); 17193a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::setupTraceContextThreadSpecific(traceContext); 17293a826f78f6313db791e6fc880439189897651b3Siva Velusamy 17393a826f78f6313db791e6fc880439189897651b3Siva Velusamy // trace command through to the host 17493a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::GLTrace_eglCreateContext(version, traceContext->getId()); 17593a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 17693a826f78f6313db791e6fc880439189897651b3Siva Velusamy 17793a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglMakeCurrent(const unsigned version, gl_hooks_t *hooks, EGLContext c) { 178a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_lock(&sGlTraceStateLock); 179a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy GLTraceState *state = sGLTraceState; 180a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy pthread_mutex_unlock(&sGlTraceStateLock); 181a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 182a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (state == NULL) return; 183a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 18493a826f78f6313db791e6fc880439189897651b3Siva Velusamy // setup per context state 185a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy GLTraceContext *traceContext = state->getTraceContext(c); 186a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy if (traceContext == NULL) { 187a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy GLTrace_eglCreateContext(version, c); 188a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy traceContext = state->getTraceContext(c); 189a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy } 190a73a97728befb5ba5ad647ab3b60058c4d536ba4Siva Velusamy 19193a826f78f6313db791e6fc880439189897651b3Siva Velusamy traceContext->hooks = hooks; 19293a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::setupTraceContextThreadSpecific(traceContext); 19393a826f78f6313db791e6fc880439189897651b3Siva Velusamy 19493a826f78f6313db791e6fc880439189897651b3Siva Velusamy // trace command through to the host 19593a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::GLTrace_eglMakeCurrent(traceContext->getId()); 19693a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 19793a826f78f6313db791e6fc880439189897651b3Siva Velusamy 19893a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglReleaseThread() { 19993a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::releaseContext(); 2000469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 2010469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 2020469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTrace_eglSwapBuffers(void *dpy, void *draw) { 2030469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy gltrace::GLTrace_eglSwapBuffers(dpy, draw); 2040469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 2050469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 20693a826f78f6313db791e6fc880439189897651b3Siva Velusamygl_hooks_t *GLTrace_getGLHooks() { 20793a826f78f6313db791e6fc880439189897651b3Siva Velusamy return gltrace::getGLHooks(); 20893a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 20993a826f78f6313db791e6fc880439189897651b3Siva Velusamy 2100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 211