glshim library updated. added changes from https://github.com/ptitSeb/glshim

This commit is contained in:
lubomyr
2015-09-03 19:01:32 +03:00
parent 2d74be14b1
commit 701b5a5f2b
100 changed files with 341 additions and 182 deletions
Regular → Executable
+1 -1
View File
@@ -44,6 +44,6 @@ LOCAL_SRC_FILES := \
LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -include include/android_debug.h
#LOCAL_LDLIBS := -ldl -llog -lEGL
#LOCAL_LDLIBS := -ldl -llog -lEGL
include $(BUILD_STATIC_LIBRARY)
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
+10 -3
View File
@@ -86,11 +86,15 @@ GLvoid *copy_gl_array_convert(const GLvoid *src,
// so we leave it in a uintptr_t and cast after incrementing
uintptr_t in = (uintptr_t)src;
in += stride*skip;
int j;
if (from == to && to_width >= width) {
GL_TYPE_SWITCH(out, dst, to,
for (int i = skip; i < count; i++) {
memcpy(out, (GLvoid *)in, from_size);
for (int j = width; j < to_width; j++) {
for (j = width; j < to_width-1; j++) {
out[j]=0;
}
for (; j < to_width; j++) {
memcpy(&out[j], filler, gl_sizeof(to));
}
out += to_width;
@@ -104,10 +108,13 @@ GLvoid *copy_gl_array_convert(const GLvoid *src,
GL_TYPE_SWITCH_MAX(out, dst, to,
for (int i = skip; i < count; i++) {
GL_TYPE_SWITCH(input, in, from,
for (int j = 0; j < width; j++) {
for (j = 0; j < width; j++) {
out[j] = input[j]*maxv/gl_max_value(from);
}
for (int j = width; j < to_width; j++) {
for (; j < to_width-1; j++) {
out[j]=0;
}
for (; j < to_width; j++) {
memcpy(&out[j], filler, gl_sizeof(to));
}
out += to_width;
+4 -4
View File
@@ -371,10 +371,10 @@
#define GL_TEXTURE_MAX_LEVEL 0x813D
/* Compressed Textures */
#define COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
/* Render Mode */
#define GL_SELECT 0x1c02
Regular → Executable
View File
+8 -6
View File
@@ -58,7 +58,7 @@ void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
//printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]);
if (state.gl_batch) flush();
LOAD_GLES_OES(glDeleteFramebuffers);
errorGL();
gles_glDeleteFramebuffers(n, framebuffers);
}
@@ -98,7 +98,7 @@ void glBindFramebuffer(GLenum target, GLuint framebuffer) {
LOAD_GLES_OES(glBindFramebuffer);
LOAD_GLES_OES(glCheckFramebufferStatus);
LOAD_GLES(glGetError);
if (target == GL_FRAMEBUFFER) {
if (fbo_read)
fbo_read = 0;
@@ -138,7 +138,9 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
LOAD_GLES(glTexImage2D);
LOAD_GLES(glBindTexture);
//printf("glFramebufferTexture2D(0x%04X, 0x%04X, 0x%04X, %u, %i)\n", target, attachment, textarget, texture, level);
if (level!=0)
return;
// Ignore Color attachment 1 .. 9
if ((attachment>=GL_COLOR_ATTACHMENT0+1) && (attachment<=GL_COLOR_ATTACHMENT0+9)) {
errorShim(GL_INVALID_ENUM);
@@ -178,7 +180,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL);
if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex);
}
if ((tex->width<32) || (tex->height<32)) {
/* if ((tex->width<32) || (tex->height<32)) {
printf("LIBGL: enlarging too-small texture for FBO\n");
tex->nwidth = (tex->nwidth<32)?32:tex->nwidth;
tex->nheight = (tex->nheight<32)?32:tex->nheight;
@@ -188,13 +190,13 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget,
if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname);
gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL);
if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex);
}
}*/
//printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type);
}
}
errorGL();
gles_glFramebufferTexture2D(target, attachment, textarget, texture, level);
gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0);
}
void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
+39 -13
View File
@@ -28,6 +28,7 @@ GLint readhack_y = 0;
GLfloat readhack_depth = 0.0f;
GLuint readhack_seq = 0;
GLuint gl_batch = 0;
GLuint gl_mergelist = 1;
__attribute__((constructor))
void initialize_glshim() {
@@ -58,6 +59,11 @@ void initialize_glshim() {
gl_batch = 0;
printf("LIBGL: Batch mode disabled\n");
}
if (env_batch && strcmp(env_batch, "2") == 0) {
gl_batch = 0;
gl_mergelist = 0;
printf("LIBGL: Batch mode disabled, merging of list disabled too\n");
}
if (gl_batch) init_batch();
state.gl_batch = gl_batch;
@@ -216,10 +222,10 @@ void glGetIntegerv(GLenum pname, GLint *params) {
// get standard ones
gles_glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, params);
// add fake DXTc
params[dummy++]=COMPRESSED_RGB_S3TC_DXT1_EXT;
params[dummy++]=COMPRESSED_RGBA_S3TC_DXT1_EXT;
params[dummy++]=COMPRESSED_RGBA_S3TC_DXT3_EXT;
params[dummy++]=COMPRESSED_RGBA_S3TC_DXT5_EXT;
params[dummy++]=GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
params[dummy++]=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
params[dummy++]=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
params[dummy++]=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
case GL_MAX_MODELVIEW_STACK_DEPTH:
*params=MAX_STACK_MODELVIEW;
@@ -360,11 +366,11 @@ void glGetFloatv(GLenum pname, GLfloat *params) {
*params=(state.buffers.elements)?state.buffers.elements->buffer:0;
break;
case GL_PIXEL_PACK_BUFFER_BINDING:
*params=(state.buffers.pack)?state.buffers.pack->buffer:0;
break;
*params=(state.buffers.pack)?state.buffers.pack->buffer:0;
break;
case GL_PIXEL_UNPACK_BUFFER_BINDING:
*params=(state.buffers.unpack)?state.buffers.unpack->buffer:0;
break;
*params=(state.buffers.unpack)?state.buffers.unpack->buffer:0;
break;
default:
errorGL();
gles_glGetFloatv(pname, params);
@@ -542,6 +548,10 @@ static inline bool should_intercept_render(GLenum mode) {
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) {
//printf("glDrawElements(0x%04X, %d, 0x%04X, %p), map=%p\n", mode, count, type, indices, (state.buffers.elements)?state.buffers.elements->data:NULL);
// TODO: split for count > 65535?
// special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex...
if (mode == GL_QUADS) while(count%4) count--;
else if (mode == GL_TRIANGLES) while(count%3) count--;
if (count<0) {
errorShim(GL_INVALID_VALUE);
return;
@@ -567,6 +577,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
list = arrays_to_renderlist(list, mode, min, max + 1 + min);
list->indices = sindices;
list->ilen = count;
list->indice_cap = count;
end_renderlist(list);
state.list.active = extend_renderlist(list);
@@ -593,6 +604,7 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
GLuint len = 0;
for (int i=0; i<count; i++)
if (len<sindices[i]) len = sindices[i]; // get the len of the arrays
len++; // lenght is max(indices) + 1 !
#define shift_pointer(a, b) \
if (state.enable.b && state.pointers.a.buffer) state.pointers.a.pointer += (uintptr_t)state.pointers.a.buffer->data;
@@ -715,6 +727,10 @@ void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indic
}
void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
// special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex...
if (mode == GL_QUADS) while(count%4) count--;
else if (mode == GL_TRIANGLES) while(count%3) count--;
if (count<0) {
errorShim(GL_INVALID_VALUE);
return;
@@ -722,6 +738,16 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) {
if (count==0) {
noerrorShim();
return;
}
// special case for (very) large GL_QUADS array
if ((mode==GL_QUADS) && (count>4*8000)) {
// split the array in manageable slice
int cnt = 4*8000;
for (int i=0; i<count; i+=4*8000) {
if (i+cnt>count) cnt = count-i;
glDrawArrays(mode, i, cnt);
}
return;
}
noerrorShim();
LOAD_GLES(glNormalPointer);
@@ -1263,7 +1289,7 @@ void glNewList(GLuint list, GLenum mode) {
state.list.name = list;
state.list.mode = mode;
// TODO: if state.list.active is already defined, we probably need to clean up here
state.list.active = state.list.first = alloc_renderlist();
state.list.active = alloc_renderlist();
state.list.compiling = true;
}
@@ -1273,7 +1299,7 @@ void glEndList() {
if (state.list.compiling) {
// Free the previous list if it exist...
free_renderlist(state.lists[list - 1]);
state.lists[list - 1] = state.list.first;
state.lists[list - 1] = GetFirst(state.list.active);
state.list.compiling = false;
end_renderlist(state.list.active);
if (gl_batch) {
@@ -1567,12 +1593,12 @@ void glBlendFunc(GLenum sfactor, GLenum dfactor) {
default:
break;
}
/*
if ((sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) {
// special case, as seen in Xash3D
// special case, as seen in Xash3D, but it breaks torus_trooper, so disabled
sfactor = GL_ONE;
}
*/
gles_glBlendFunc(sfactor, dfactor);
}
+1 -1
View File
@@ -51,7 +51,7 @@ GLfloat *gen_stipple_tex_coords(GLfloat *vert, int length) {
y2 = *vertPos++;
vertPos++;
len = sqrt(pow(x2-x1, 2) + pow(y2-y1, 2)) / stippleFactor * 16;
len = sqrtf(powf(x2-x1, 2) + powf(y2-y1, 2)) / stippleFactor * 16;
*texPos++ = 0;
*texPos++ = 0;
Regular → Executable
View File
+218 -120
View File
@@ -52,9 +52,12 @@ renderlist_t *alloc_renderlist() {
list->lightmodel = NULL;
list->lightmodelparam = GL_LIGHT_MODEL_AMBIENT;
list->indices = NULL;
list->indice_cap = 0;
list->set_texture = false;
list->texture = 0;
list->target_texture = GL_TEXTURE_2D;
list->polygon_mode = 0;
list->fog_op = 0;
list->prev = NULL;
list->next = NULL;
@@ -78,7 +81,9 @@ bool ispurerender_renderlist(renderlist_t *list) {
return false;
if (list->popattribute)
return false;
if (list->material || list->light)
if (list->material || list->light || list->lightmodel)
return false;
if (list->fog_op)
return false;
if (list->texgen)
return false;
@@ -110,7 +115,12 @@ int rendermode_dimensions(GLenum mode) {
return 0;
}
extern GLuint gl_mergelist;
bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) {
if (!gl_mergelist)
return false;
// check if 2 "pure rendering" list are compatible for merge
if (a->mode_init != b->mode_init) {
int a_mode = rendermode_dimensions(a->mode_init);
@@ -136,13 +146,17 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) {
return false;
if ((a->secondary==NULL) != (b->secondary==NULL))
return false;
// check the textures
for (int i=0; i<MAX_TEX; i++)
if ((a->tex[i]==NULL) != (b->tex[i]==NULL))
return false;
if ((a->set_texture==b->set_texture) && (a->texture != b->texture))
if ((a->set_texture==b->set_texture) && ((a->texture != b->texture) || (a->target_texture != b->target_texture)))
return false;
if (!a->set_texture && b->set_texture)
return false;
// polygon mode
if(a->polygon_mode!=b->polygon_mode)
return false;
// Check the size of a list, if it"s too big, don't merge...
if ((a->len+b->len)>30000)
@@ -153,84 +167,86 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) {
return true;
}
void renderlist_createindices(renderlist_t *a) {
void renderlist_createindices(renderlist_t *a, GLushort *indices, int count) {
int ilen = a->len;
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i = 0; i<ilen; i++) {
a->indices[i] = i;
indices[i] = i+count;
}
a->ilen = ilen;
}
#define vind(a) (ind)?ind[(a)]:(a)
#define vind(a) (((ind)?ind[(a)]:(a))+count)
void renderlist_lineloop_lines(renderlist_t *a) {
void renderlist_lineloop_lines(renderlist_t *a, GLushort *indices, int count) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
int ilen = len*2; // new size is 2* + return
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i = 0; i<ilen-1; i++) {
a->indices[i] = vind((i+1)/2);
indices[i] = vind((i+1)/2);
}
// go back to initial point
a->indices[ilen-1] = a->indices[0];
a->ilen = ilen;
if ((ind) && !a->shared_arrays) free(ind);
a->mode = GL_LINES;
indices[ilen-1] = indices[0];
}
void renderlist_linestrip_lines(renderlist_t *a) {
void renderlist_linestrip_lines(renderlist_t *a, GLushort *indices, int count) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
int ilen = len*2-2; // new size is 2*
if (ilen<0) ilen=0;
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i = 0; i<ilen; i++) {
a->indices[i] = vind((i+1)/2);
indices[i] = vind((i+1)/2);
}
a->ilen = ilen;
if ((ind) && !a->shared_arrays) free(ind);
a->mode = GL_LINES;
}
void renderlist_triangletrip_triangles(renderlist_t *a) {
void renderlist_triangletrip_triangles(renderlist_t *a, GLushort *indices, int count) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
int ilen = (len-2)*3;
if (ilen<0) ilen=0;
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i = 2; i<len; i++) {
a->indices[(i-2)*3+(i%2)] = vind(i-2);
a->indices[(i-2)*3+1-(i%2)] = vind(i-1);
a->indices[(i-2)*3+2] = vind(i);
indices[(i-2)*3+(i%2)] = vind(i-2);
indices[(i-2)*3+1-(i%2)] = vind(i-1);
indices[(i-2)*3+2] = vind(i);
}
a->ilen = ilen;
if ((ind) && !a->shared_arrays) free(ind);
a->mode = GL_TRIANGLES;
}
void renderlist_trianglefan_triangles(renderlist_t *a) {
void renderlist_trianglefan_triangles(renderlist_t *a, GLushort *indices, int count) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
int ilen = (len-2)*3;
if (ilen<0) ilen=0;
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i = 2; i<len; i++) {
a->indices[(i-2)*3+0] = vind(0);
a->indices[(i-2)*3+1] = vind(i-1);
a->indices[(i-2)*3+2] = vind(i);
indices[(i-2)*3+0] = vind(0);
indices[(i-2)*3+1] = vind(i-1);
indices[(i-2)*3+2] = vind(i);
}
a->ilen = ilen;
if ((ind) && !a->shared_arrays) free(ind);
a->mode = GL_TRIANGLES;
}
void renderlist_quads_triangles(renderlist_t *a) {
void renderlist_quads_triangles(renderlist_t *a, GLushort *indices, int count) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
// len must be a multiple of 4 !
len &= ~3; // discard extra vertex...
int ilen = len*3/2;
for (int i=0, j=0; i+3<len; i+=4, j+=6) {
indices[j+0] = vind(i+0);
indices[j+1] = vind(i+1);
indices[j+2] = vind(i+2);
indices[j+3] = vind(i+0);
indices[j+4] = vind(i+2);
indices[j+5] = vind(i+3);
}
}
#undef vind
#define vind(a) ((ind)?ind[(a)]:(a))
void renderlist_quads2triangles(renderlist_t *a) {
GLushort *ind = a->indices;
int len = (ind)? a->ilen:a->len;
// len must be a multiple of 4 !
len &= ~3; // discard extra vertex...
int ilen = len*3/2;
a->indices = (GLushort*)malloc(ilen*sizeof(GLushort));
for (int i=0, j=0; i<len; i+=4, j+=6) {
for (int i=0, j=0; i+3<len; i+=4, j+=6) {
a->indices[j+0] = vind(i+0);
a->indices[j+1] = vind(i+1);
a->indices[j+2] = vind(i+2);
@@ -245,105 +261,93 @@ void renderlist_quads_triangles(renderlist_t *a) {
}
#undef vind
void append_renderlist(renderlist_t *a, renderlist_t *b) {
// append all draw elements of b in a
// check if "a" needs to be converted
int renderlist_getindicesize(renderlist_t *a) {
int ilen_a;
switch (a->mode) {
case GL_LINE_LOOP:
renderlist_lineloop_lines(a);
ilen_a = (((a->indices)? a->ilen:a->len)-2)*3;
if (ilen_a<0) ilen_a=1; // special borked case...
break;
case GL_LINE_STRIP:
renderlist_linestrip_lines(a);
ilen_a = (((a->indices)? a->ilen:a->len)*2)-2;
if (ilen_a<0) ilen_a=1; // special borked case...
break;
case GL_QUAD_STRIP:
case GL_TRIANGLE_STRIP:
renderlist_triangletrip_triangles(a);
ilen_a = (((a->indices)? a->ilen:a->len)-2)*3;
if (ilen_a<0) ilen_a=1; // special borked case...
break;
case GL_TRIANGLE_FAN:
case GL_POLYGON:
renderlist_trianglefan_triangles(a);
ilen_a = (((a->indices)? a->ilen:a->len)-2)*3;
if (ilen_a<0) ilen_a=1; // special borked case...
break;
case GL_QUADS:
renderlist_quads_triangles(a);
ilen_a = ((((a->indices)? a->ilen:a->len)&~3)*3)/2;
break;
default:
if (a->shared_arrays && a->indices) {
// copy shared indices to non-shared copy
GLushort *ind = a->indices;
a->indices = (GLushort*)malloc(a->ilen*sizeof(GLushort));
memcpy(a->indices, ind, a->ilen*sizeof(GLushort));
}
ilen_a = a->ilen;
break;
}
// save old b indices in case of shared
GLushort *ind_b = b->indices;
unsigned long ilen_b = b->ilen;
// check if "b" needs to be converted
switch (b->mode) {
case GL_LINE_LOOP:
renderlist_lineloop_lines(b);
break;
case GL_LINE_STRIP:
renderlist_linestrip_lines(b);
break;
case GL_QUAD_STRIP:
case GL_TRIANGLE_STRIP:
renderlist_triangletrip_triangles(b);
break;
case GL_TRIANGLE_FAN:
case GL_POLYGON:
renderlist_trianglefan_triangles(b);
break;
case GL_QUADS:
renderlist_quads_triangles(b);
break;
default:
if (b->shared_arrays && b->indices) {
// copy shared indices to non-shared copy
b->indices = (GLushort*)malloc(b->ilen*sizeof(GLushort));
memcpy(b->indices, ind_b, b->ilen*sizeof(GLushort));
}
break;
}
// check for differences in "indices" in both list
if ((a->indices==NULL) != (b->indices==NULL)) {
if (a->indices==NULL) renderlist_createindices(a);
if (b->indices==NULL) renderlist_createindices(b);
}
return ilen_a;
}
void append_renderlist(renderlist_t *a, renderlist_t *b) {
// append all draw elements of b in a
// check the final indice size of a and b
int ilen_a = renderlist_getindicesize(a);
int ilen_b = renderlist_getindicesize(b);
// lets append all the arrays
unsigned long cap = a->cap;
//while (a->len + b->len >= cap) cap += DEFAULT_RENDER_LIST_CAPACITY;
if (a->len + b->len >= cap) cap += b->cap;
if (a->len + b->len >= cap) cap += b->cap + DEFAULT_RENDER_LIST_CAPACITY;
if (a->shared_arrays) {
// Unshare if shared (shared array are not used for now)
a->cap = cap;
GLfloat *tmp;
tmp = a->vert;
a->vert = alloc_sublist(3, cap);
memcpy(a->vert, tmp, 3*a->len*sizeof(GLfloat));
if (tmp) {
a->vert = alloc_sublist(3, cap);
memcpy(a->vert, tmp, 3*a->len*sizeof(GLfloat));
}
tmp = a->normal;
a->normal = alloc_sublist(3, cap);
memcpy(a->normal, tmp, 3*a->len*sizeof(GLfloat));
if (tmp) {
a->normal = alloc_sublist(3, cap);
memcpy(a->normal, tmp, 3*a->len*sizeof(GLfloat));
}
tmp = a->color;
a->color = alloc_sublist(4, cap);
memcpy(a->color, tmp, 4*a->len*sizeof(GLfloat));
if (tmp) {
a->color = alloc_sublist(4, cap);
memcpy(a->color, tmp, 4*a->len*sizeof(GLfloat));
}
tmp = a->secondary;
a->secondary = alloc_sublist(4, cap);
memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat));
if (tmp) {
a->secondary = alloc_sublist(4, cap);
memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat));
}
for (int i=0; i<MAX_TEX; i++) {
tmp = a->tex[i];
a->tex[i] = alloc_sublist(2, cap);
memcpy(a->tex[i], tmp, 2*a->len*sizeof(GLfloat));
if (tmp) {
a->tex[i] = alloc_sublist(2, cap);
memcpy(a->tex[i], tmp, 2*a->len*sizeof(GLfloat));
}
}
if (a->indices) {
GLushort* tmpi = a->indices;
a->indice_cap = ((ilen_a)?ilen_a:a->len) + ((ilen_b)?ilen_b:b->len);
if (a->indice_cap > 48) a->indice_cap = (a->indice_cap+511)&~511;
a->indices = (GLushort*)malloc(a->indice_cap*sizeof(GLushort));
memcpy(a->indices, tmpi, a->ilen*sizeof(GLushort));
}
a->shared_arrays = false;
} else {
if (a->cap != cap) {
if (a->cap < cap) {
a->cap = cap;
realloc_sublist(a->vert, 3, cap);
realloc_sublist(a->normal, 3, cap);
realloc_sublist(a->color, 4, cap);
realloc_sublist(a->secondary, 4, cap);
if (a->vert) realloc_sublist(a->vert, 3, cap);
if (a->normal) realloc_sublist(a->normal, 3, cap);
if (a->color) realloc_sublist(a->color, 4, cap);
if (a->secondary) realloc_sublist(a->secondary, 4, cap);
for (int i=0; i<MAX_TEX; i++)
realloc_sublist(a->tex[i], 2, cap);
if (a->tex[i]) realloc_sublist(a->tex[i], 2, cap);
}
}
// append arrays
@@ -355,22 +359,109 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) {
if (a->tex[i]) memcpy(a->tex[i]+a->len*2, b->tex[i], b->len*2*sizeof(GLfloat));
// indices
if (a->indices) {
a->indices = (GLushort*)realloc(a->indices, (a->ilen+b->ilen)*sizeof(GLushort));
for (int i=0; i<b->ilen; i++)
a->indices[a->ilen+i]=b->indices[i]+a->len;
if (ilen_a + ilen_b)
{
// alloc or realloc a->indices first...
int capindices = ((ilen_a)?ilen_a:a->len) + ((ilen_b)?ilen_b:b->len);
if (capindices > 48) capindices = (capindices+511)&~511;
#define alloc_a_indices \
newind=(GLushort*)malloc(capindices*sizeof(GLushort))
#define copy_a_indices \
if (a->indices) free(a->indices); \
a->indices = newind; \
a->indice_cap = capindices
// check if "a" needs to be converted
GLushort *newind=NULL;
switch (a->mode) {
case GL_LINE_LOOP:
alloc_a_indices;
renderlist_lineloop_lines(a, newind, 0);
a->mode = GL_LINES;
copy_a_indices;
break;
case GL_LINE_STRIP:
alloc_a_indices;
renderlist_linestrip_lines(a, newind, 0);
a->mode = GL_LINES;
copy_a_indices;
break;
case GL_QUAD_STRIP:
case GL_TRIANGLE_STRIP:
alloc_a_indices;
renderlist_triangletrip_triangles(a, newind, 0);
a->mode = GL_TRIANGLES;
copy_a_indices;
break;
case GL_TRIANGLE_FAN:
case GL_POLYGON:
alloc_a_indices;
renderlist_trianglefan_triangles(a, newind, 0);
a->mode = GL_TRIANGLES;
copy_a_indices;
break;
case GL_QUADS:
alloc_a_indices;
renderlist_quads_triangles(a, newind, 0);
a->mode = GL_TRIANGLES;
copy_a_indices;
break;
default:
if (!ilen_a) {
// no a->indices, must alloc and fill one
alloc_a_indices;
renderlist_createindices(a, newind, 0);
ilen_a = a->len;
copy_a_indices;
} else {
// a->indices already exist, just check if need to adjust its size
if (a->indice_cap < capindices) {
a->indices = (GLushort*)realloc(a->indices, capindices*sizeof(GLushort));
a->indice_cap = capindices;
}
}
break;
}
#undef copy_a_indices
#undef alloc_a_indices
a->ilen = ilen_a;
// then append b
switch (b->mode) {
case GL_LINE_LOOP:
renderlist_lineloop_lines(b, a->indices + ilen_a, a->len);
break;
case GL_LINE_STRIP:
renderlist_linestrip_lines(b, a->indices + ilen_a, a->len);
break;
case GL_QUAD_STRIP:
case GL_TRIANGLE_STRIP:
renderlist_triangletrip_triangles(b, a->indices + ilen_a, a->len);
break;
case GL_TRIANGLE_FAN:
case GL_POLYGON:
renderlist_trianglefan_triangles(b, a->indices + ilen_a, a->len);
break;
case GL_QUADS:
renderlist_quads_triangles(b, a->indices + ilen_a, a->len);
break;
default:
// no transform here, just take (or create) the indice list as-is
if (!b->ilen) {
// append a newly created indice list
renderlist_createindices(b, a->indices + ilen_a, a->len);
ilen_b = b->len;
} else {
// append existing one
newind = a->indices+ilen_a;
for(int i=0; i<b->ilen; i++)
newind[i] = b->indices[i]+a->len;
}
break;
}
}
// lenghts
a->len += b->len;
a->ilen += b->ilen;
if (b->shared_arrays) {
// restored shared indices copy...
if (b->indices) free(b->indices);
b->indices = ind_b;
b->ilen = ilen_b;
}
a->ilen += ilen_b;
//all done
return;
}
@@ -497,10 +588,10 @@ void end_renderlist(renderlist_t *list) {
}
switch (list->mode) {
case GL_QUADS:
if (list->len==4) {
if (((list->indices) && (list->ilen==4)) || ((list->indices==NULL) && (list->len==4))) {
list->mode = GL_TRIANGLE_FAN;
} else {
renderlist_quads_triangles(list);
renderlist_quads2triangles(list);
}
break;
case GL_POLYGON:
@@ -1181,5 +1272,12 @@ void rlPushCall(renderlist_t *list, packed_call_t *data) {
}
cl->calls[cl->len++] = data;
}
renderlist_t* GetFirst(const renderlist_t* list) {
while(list->prev)
list = list->prev;
return list;
}
#undef alloc_sublist
#undef realloc_sublist
+4 -1
View File
@@ -101,6 +101,7 @@ typedef struct _renderlist_t {
GLfloat *secondary;
GLfloat *tex[MAX_TEX];
GLushort *indices;
unsigned int indice_cap;
GLuint glcall_list;
rasterlist_t *raster;
@@ -134,10 +135,12 @@ typedef struct _renderlist_t {
} renderlist_t;
#define DEFAULT_CALL_LIST_CAPACITY 20
#define DEFAULT_RENDER_LIST_CAPACITY 20
#define DEFAULT_RENDER_LIST_CAPACITY 64
#define NewStage(l, s) if (l->stage+StageExclusive[l->stage] > s) {l = extend_renderlist(l);} l->stage = s
renderlist_t* GetFirst(const renderlist_t* list);
extern renderlist_t *alloc_renderlist();
extern renderlist_t *extend_renderlist(renderlist_t *list);
extern void free_renderlist(renderlist_t *list);
View File
View File
+3 -3
View File
@@ -807,10 +807,10 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new,
GLuint pixel_size, new_width, new_height;
new_width = width / 4;
new_height = height / 4;
if (new_width*4!=width || new_height*4!=height) {
printf("LIBGL: quarterscaling %ux%u failed", width, height);
/* if (new_width*4!=width || new_height*4!=height) {
printf("LIBGL: quarterscaling %ux%u failed\n", width, height);
return false;
}
}*/
// printf("LIBGL: quarterscaling %ux%u -> %ux%u\n", width, height, new_width, new_height);
const colorlayout_t *src_color;
src_color = get_color_map(format);
+2
View File
@@ -22,6 +22,8 @@ typedef struct {
GLsizei height;
} viewport_t;
extern viewport_t viewport;
extern GLfloat raster_scale[4];
extern GLfloat raster_bias[4];
+1 -1
View File
@@ -68,7 +68,6 @@ typedef struct {
typedef struct {
renderlist_t *active;
renderlist_t *first;
GLboolean compiling;
GLboolean locked;
GLuint base;
@@ -141,6 +140,7 @@ typedef struct {
int shim_error;
GLenum last_error;
GLuint gl_batch;
GLint vp[4];
} glstate_t;
#endif
+50 -29
View File
@@ -187,6 +187,7 @@ int texshrink = 0;
int texdump = 0;
int alphahack = 0;
int texstream = 0;
int copytex = 0;
static int default_tex_mipmap = 0;
static int proxy_width = 0;
@@ -258,11 +259,15 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
}
if (env_shrink && strcmp(env_shrink, "5") == 0) {
texshrink = 5;
printf("LIBGL: Texture shink, mode 5 selected (every > 256 is downscaled to 256 )\n");
printf("LIBGL: Texture shink, mode 5 selected (every > 256 is downscaled to 256 ), but not for empty texture\n");
}
if (env_shrink && strcmp(env_shrink, "6") == 0) {
texshrink = 6;
printf("LIBGL: Texture shink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 )\n");
printf("LIBGL: Texture shink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture\n");
}
if (env_shrink && strcmp(env_shrink, "7") == 0) {
texshrink = 20;
printf("LIBGL: Texture shink, mode 7 selected (only > 512 /2 ), but not for empty texture\n");
}
char *env_dump = getenv("LIBGL_TEXDUMP");
if (env_dump && strcmp(env_dump, "1") == 0) {
@@ -285,6 +290,11 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
printf("LIBGL: Streaming texture %s\n",(texstream)?"forced":"not available");
//FreeStreamed(AddStreamed(1024, 512, 0));
}
char *env_copy = getenv("LIBGL_COPY");
if (env_copy && strcmp(env_copy, "1") == 0) {
printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n");
copytex = 1;
}
tested_env = true;
}
@@ -335,7 +345,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat,
bound->shrink = 1;
}
}
if (bound && (texshrink==2 || texshrink==3)) {
if (bound && (texshrink==2 || texshrink==3 || texshrink==7)) {
if (((width%2==0) && (height%2==0)) &&
((width > ((texshrink==2)?512:256)) && (height > 8)) || ((height > ((texshrink==2)?512:256)) && (width > 8))) {
GLvoid *out = pixels;
@@ -1234,12 +1244,16 @@ if (state.gl_batch) flush();
free(tmp);
}
} else {
void* tmp = malloc(width*height*4);
GLenum format = (bound)?bound->format:GL_RGBA;
GLenum type = (bound)?bound->type:GL_UNSIGNED_BYTE;
glReadPixels(x, y, width, height, format, type, tmp);
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, tmp);
free(tmp);
if (copytex) {
gles_glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
} else {
void* tmp = malloc(width*height*4);
GLenum format = (bound)?bound->format:GL_RGBA;
GLenum type = (bound)?bound->type:GL_UNSIGNED_BYTE;
glReadPixels(x, y, width, height, format, type, tmp);
glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, tmp);
free(tmp);
}
}
// "Remap" if buffer mapped...
state.buffers.pack = pack;
@@ -1264,12 +1278,17 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin
glbuffer_t *unpack = state.buffers.unpack;
state.buffers.pack = NULL;
state.buffers.unpack = NULL;
void* tmp = malloc(width*height*4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
glTexImage2D(target, level, internalformat, width, height, border, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
free(tmp);
if (copytex) {
LOAD_GLES(glCopyTexImage2D);
gles_glCopyTexImage2D(target, level, GL_RGB, x, y, width, height, border);
} else {
void* tmp = malloc(width*height*4);
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
glTexImage2D(target, level, internalformat, width, height, border, GL_RGBA, GL_UNSIGNED_BYTE, tmp);
free(tmp);
}
// "Remap" if buffer mapped...
state.buffers.pack = pack;
state.buffers.unpack = unpack;
@@ -1281,10 +1300,10 @@ void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLin
GLboolean isDXTc(GLenum format) {
switch (format) {
case COMPRESSED_RGB_S3TC_DXT1_EXT:
case COMPRESSED_RGBA_S3TC_DXT1_EXT:
case COMPRESSED_RGBA_S3TC_DXT3_EXT:
case COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
return true;
}
return false;
@@ -1318,12 +1337,12 @@ GLvoid *uncompressDXTc(GLsizei width, GLsizei height, GLenum format, GLsizei ima
// uncompress loop
int blocksize;
switch (format) {
case COMPRESSED_RGB_S3TC_DXT1_EXT:
case COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
blocksize = 8;
break;
case COMPRESSED_RGBA_S3TC_DXT3_EXT:
case COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
blocksize = 16;
break;
}
@@ -1331,14 +1350,14 @@ GLvoid *uncompressDXTc(GLsizei width, GLsizei height, GLenum format, GLsizei ima
for (int y=0; y<height; y+=4) {
for (int x=0; x<width; x+=4) {
switch(format) {
case COMPRESSED_RGB_S3TC_DXT1_EXT:
case COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
DecompressBlockDXT1(x, y, width, (uint8_t*)src, pixels);
break;
case COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
DecompressBlockDXT3(x, y, width, (uint8_t*)src, pixels);
break;
case COMPRESSED_RGBA_S3TC_DXT5_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
DecompressBlockDXT5(x, y, width, (uint8_t*)src, pixels);
break;
}
@@ -1408,12 +1427,14 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
}
// automaticaly reduce the pixel size
half=pixels;
state.texture.bound[state.texture.active]->alpha = (internalformat==COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true;
state.texture.bound[state.texture.active]->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true;
state.texture.bound[state.texture.active]->format = GL_RGBA; //internalformat;
state.texture.bound[state.texture.active]->type = GL_UNSIGNED_SHORT_4_4_4_4; //GL_UNSIGNED_BYTE;
state.texture.bound[state.texture.active]->type = GL_UNSIGNED_SHORT_4_4_4_4;
state.texture.bound[state.texture.active]->compressed = true;
if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE))
fact = 1;
else
state.texture.bound[state.texture.active]->type = GL_UNSIGNED_BYTE;
} else {
half = NULL;
fact = 1;
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File