1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
/*
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef ANDROID_GLES2_DBG_HEADER_H
#define ANDROID_GLES2_DBG_HEADER_H
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <cutils/log.h>
#include <utils/Timers.h>
#include "hooks.h"
#include "glesv2dbg.h"
#define GL_ENTRY(_r, _api, ...) _r Debug_##_api ( __VA_ARGS__ );
#include "glesv2dbg_functions.h"
#include "debugger_message.pb.h"
using namespace android;
using namespace com::android;
#ifndef __location__
#define __HIERALLOC_STRING_0__(s) #s
#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
#endif
#undef assert
#define assert(expr) if (!(expr)) { LOGD("\n*\n*\n* assert: %s at %s \n*\n*", #expr, __location__); int * x = 0; *x = 5; }
//#undef LOGD
//#define LOGD(...)
namespace android
{
struct GLFunctionBitfield {
unsigned char field [24]; // 8 * 24 = 192
void Bit(const glesv2debugger::Message_Function function, bool bit) {
const unsigned byte = function / 8, mask = 1 << (function % 8);
if (bit)
field[byte] |= mask;
else
field[byte] &= ~mask;
}
bool Bit(const glesv2debugger::Message_Function function) const {
const unsigned byte = function / 8, mask = 1 << (function % 8);
return field[byte] & mask;
}
};
struct DbgContext {
private:
static const unsigned int LZF_CHUNK_SIZE = 256 * 1024;
char * lzf_buf; // malloc / free; for lzf chunk compression
// used as buffer and reference frame for ReadPixels; malloc/free
unsigned * lzf_ref [2];
unsigned lzf_readIndex; // 0 or 1
unsigned lzf_refSize, lzf_refBufSize; // bytes
public:
const unsigned version; // 0 is GLES1, 1 is GLES2
const gl_hooks_t * const hooks;
const unsigned MAX_VERTEX_ATTRIBS;
GLFunctionBitfield expectResponse;
struct VertexAttrib {
GLenum type; // element data type
unsigned size; // number of data per element
unsigned stride; // calculated number of bytes between elements
const void * ptr;
unsigned elemSize; // calculated number of bytes per element
GLuint buffer; // buffer name
GLboolean normalized : 1;
GLboolean enabled : 1;
VertexAttrib() : type(0), size(0), stride(0), ptr(NULL), elemSize(0),
buffer(0), normalized(0), enabled(0) {}
} * vertexAttribs;
bool hasNonVBOAttribs; // whether any enabled vertexAttrib is user pointer
struct VBO {
const GLuint name;
const GLenum target;
VBO * next;
void * data; // malloc/free
unsigned size; // in bytes
VBO(const GLuint name, const GLenum target, VBO * head) : name(name),
target(target), next(head), data(NULL), size(0) {}
} * indexBuffers; // linked list of all index buffers
VBO * indexBuffer; // currently bound index buffer
GLuint program;
unsigned maxAttrib; // number of slots used by program
DbgContext(const unsigned version, const gl_hooks_t * const hooks,
const unsigned MAX_VERTEX_ATTRIBS);
~DbgContext();
void Fetch(const unsigned index, std::string * const data) const;
void Compress(const void * in_data, unsigned in_len, std::string * const outStr);
void * GetReadPixelsBuffer(const unsigned size);
bool IsReadPixelBuffer(const void * const ptr) {
return ptr == lzf_ref[lzf_readIndex];
}
void CompressReadPixelBuffer(std::string * const outStr);
void glUseProgram(GLuint program);
void glEnableVertexAttribArray(GLuint index);
void glDisableVertexAttribArray(GLuint index);
void glVertexAttribPointer(GLuint indx, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const GLvoid* ptr);
void glBindBuffer(GLenum target, GLuint buffer);
void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
void glDeleteBuffers(GLsizei n, const GLuint *buffers);
};
DbgContext * getDbgContextThreadSpecific();
struct FunctionCall {
virtual const int * operator()(gl_hooks_t::gl_t const * const _c,
glesv2debugger::Message & msg) = 0;
virtual ~FunctionCall() {}
};
// move these into DbgContext as static
extern bool capture;
extern int timeMode; // SYSTEM_TIME_
extern int clientSock, serverSock;
unsigned GetBytesPerPixel(const GLenum format, const GLenum type);
// every Debug_gl* function calls this to send message to client and possibly receive commands
int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
const glesv2debugger::Message_Function function);
void Receive(glesv2debugger::Message & cmd);
float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd);
const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
glesv2debugger::Message & msg, const int * const prevRet);
}; // namespace android {
#endif // #ifndef ANDROID_GLES2_DBG_HEADER_H
|