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 3693a826f78f6313db791e6fc880439189897651b3Siva Velusamystatic GLTraceState *sGLTraceState; 373f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamystatic pthread_t sReceiveThreadId; 383f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 393f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy/** 403f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy * Task that monitors the control stream from the host and updates 413f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy * the trace status according to commands received from the host. 423f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy */ 433f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamystatic void *commandReceiveTask(void *arg) { 443f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy GLTraceState *state = (GLTraceState *)arg; 453f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy TCPStream *stream = state->getStream(); 463f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 472fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // The control stream always receives an integer size of the 482fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // command buffer, followed by the actual command buffer. 492fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmdSize; 502fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 512fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // Command Buffer 522fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy void *cmdBuf = NULL; 532fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmdBufSize = 0; 542fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 553f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy enum TraceSettingsMasks { 563f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_FB_ON_EGLSWAP_MASK = 1 << 0, 573f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_FB_ON_GLDRAW_MASK = 1 << 1, 583f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK = 1 << 2, 593f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy }; 603f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 613f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy while (true) { 622fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // read command size 632fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (stream->receive(&cmdSize, sizeof(uint32_t)) < 0) { 643f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy break; 653f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy } 662fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdSize = ntohl(cmdSize); 672fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 682fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // ensure command buffer is of required size 692fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdBufSize < cmdSize) { 702fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy free(cmdBuf); 712fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdBufSize = cmdSize; 722fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy cmdBuf = malloc(cmdSize); 732fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdBuf == NULL) 742fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy break; 752fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 763f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 772fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // receive the command 782fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (stream->receive(cmdBuf, cmdSize) < 0) { 792fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy break; 802fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 812fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 822fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy if (cmdSize != sizeof(uint32_t)) { 832fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // Currently, we only support commands that are a single integer, 842fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy // so we skip all other commands 852fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy continue; 862fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy } 872fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 882fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy uint32_t cmd = ntohl(*(uint32_t*)cmdBuf); 893f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 903f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0; 913f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0; 923f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy bool collectTextureData = (cmd & READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK) != 0; 933f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 943f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectFbOnEglSwap(collectFbOnEglSwap); 953f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectFbOnGlDraw(collectFbOnGlDraw); 963f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy state->setCollectTextureDataOnGlTexImage(collectTextureData); 973f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 983f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy ALOGD("trace options: eglswap: %d, gldraw: %d, texImage: %d", 993f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData); 1003f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy } 1013f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 1022fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy ALOGE("Stopping OpenGL Trace Command Receiver\n"); 1032fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy 1042fdcc81ddfdbdfbbde63bd64e9ac9272b5417553Siva Velusamy free(cmdBuf); 1053f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy return NULL; 1063f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy} 1070469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1080469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTrace_start() { 1090832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy char udsName[PROPERTY_VALUE_MAX]; 1100469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1110832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy property_get("debug.egl.debug_portname", udsName, "gltrace"); 1120832fb6407d1c85cba20a8cc0aff828db3c134deSiva Velusamy int clientSocket = gltrace::acceptClientConnection(udsName); 11393a826f78f6313db791e6fc880439189897651b3Siva Velusamy if (clientSocket < 0) { 114e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error creating GLTrace server socket. Quitting application."); 11593a826f78f6313db791e6fc880439189897651b3Siva Velusamy exit(-1); 11693a826f78f6313db791e6fc880439189897651b3Siva Velusamy } 11793a826f78f6313db791e6fc880439189897651b3Siva Velusamy 11893a826f78f6313db791e6fc880439189897651b3Siva Velusamy // create communication channel to the host 11993a826f78f6313db791e6fc880439189897651b3Siva Velusamy TCPStream *stream = new TCPStream(clientSocket); 12093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 12193a826f78f6313db791e6fc880439189897651b3Siva Velusamy // initialize tracing state 12293a826f78f6313db791e6fc880439189897651b3Siva Velusamy sGLTraceState = new GLTraceState(stream); 1233f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy 1243f194e6e3a62cbb846e8948eac8e4ce9aa7444a6Siva Velusamy pthread_create(&sReceiveThreadId, NULL, commandReceiveTask, sGLTraceState); 1250469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1260469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1270469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTrace_stop() { 12893a826f78f6313db791e6fc880439189897651b3Siva Velusamy delete sGLTraceState; 12993a826f78f6313db791e6fc880439189897651b3Siva Velusamy sGLTraceState = NULL; 1300469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1310469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 13293a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglCreateContext(int version, EGLContext c) { 13393a826f78f6313db791e6fc880439189897651b3Siva Velusamy // update trace state for new EGL context 13493a826f78f6313db791e6fc880439189897651b3Siva Velusamy GLTraceContext *traceContext = sGLTraceState->createTraceContext(version, c); 13593a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::setupTraceContextThreadSpecific(traceContext); 13693a826f78f6313db791e6fc880439189897651b3Siva Velusamy 13793a826f78f6313db791e6fc880439189897651b3Siva Velusamy // trace command through to the host 13893a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::GLTrace_eglCreateContext(version, traceContext->getId()); 13993a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 14093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14193a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglMakeCurrent(const unsigned version, gl_hooks_t *hooks, EGLContext c) { 14293a826f78f6313db791e6fc880439189897651b3Siva Velusamy // setup per context state 14393a826f78f6313db791e6fc880439189897651b3Siva Velusamy GLTraceContext *traceContext = sGLTraceState->getTraceContext(c); 14493a826f78f6313db791e6fc880439189897651b3Siva Velusamy traceContext->hooks = hooks; 14593a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::setupTraceContextThreadSpecific(traceContext); 14693a826f78f6313db791e6fc880439189897651b3Siva Velusamy 14793a826f78f6313db791e6fc880439189897651b3Siva Velusamy // trace command through to the host 14893a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::GLTrace_eglMakeCurrent(traceContext->getId()); 14993a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 15093a826f78f6313db791e6fc880439189897651b3Siva Velusamy 15193a826f78f6313db791e6fc880439189897651b3Siva Velusamyvoid GLTrace_eglReleaseThread() { 15293a826f78f6313db791e6fc880439189897651b3Siva Velusamy gltrace::releaseContext(); 1530469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1540469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 1550469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamyvoid GLTrace_eglSwapBuffers(void *dpy, void *draw) { 1560469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy gltrace::GLTrace_eglSwapBuffers(dpy, draw); 1570469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 1580469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy 15993a826f78f6313db791e6fc880439189897651b3Siva Velusamygl_hooks_t *GLTrace_getGLHooks() { 16093a826f78f6313db791e6fc880439189897651b3Siva Velusamy return gltrace::getGLHooks(); 16193a826f78f6313db791e6fc880439189897651b3Siva Velusamy} 16293a826f78f6313db791e6fc880439189897651b3Siva Velusamy 1630469dd6d55fa331bfd7de9431da98b6340d82271Siva Velusamy} 164