[client] egl: fix non-streaming texture updates

This commit is contained in:
Geoffrey McRae 2020-05-29 16:54:25 +10:00
parent e8c949c1e7
commit fcbdf7ba4f
2 changed files with 37 additions and 39 deletions

View File

@ -1 +1 @@
B2-rc2-6-g28c93ef5ac+1 B2-rc2-7-ge8c949c1e7+1

View File

@ -74,6 +74,7 @@ struct EGL_Texture
size_t pboBufferSize; size_t pboBufferSize;
union TexState state; union TexState state;
int textureCount;
struct Tex tex[TEXTURE_COUNT]; struct Tex tex[TEXTURE_COUNT];
}; };
@ -98,7 +99,7 @@ void egl_texture_free(EGL_Texture ** texture)
if ((*texture)->planeCount > 0) if ((*texture)->planeCount > 0)
glDeleteSamplers((*texture)->planeCount, (*texture)->samplers); glDeleteSamplers((*texture)->planeCount, (*texture)->samplers);
for(int i = 0; i < ((*texture)->streaming ? TEXTURE_COUNT : 1); ++i) for(int i = 0; i < (*texture)->textureCount; ++i)
{ {
struct Tex * t = &(*texture)->tex[i]; struct Tex * t = &(*texture)->tex[i];
if (t->hasPBO) if (t->hasPBO)
@ -134,6 +135,7 @@ static bool egl_texture_map(EGL_Texture * texture, uint8_t i)
GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_UNSYNCHRONIZED_BIT |
GL_MAP_INVALIDATE_BUFFER_BIT GL_MAP_INVALIDATE_BUFFER_BIT
); );
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
if (!texture->tex[i].map) if (!texture->tex[i].map)
{ {
@ -144,17 +146,6 @@ static bool egl_texture_map(EGL_Texture * texture, uint8_t i)
return true; return true;
} }
static bool egl_texture_map_all(EGL_Texture * texture)
{
// release old PBOs and delete and re-create the buffers
for(int i = 0; i < TEXTURE_COUNT; ++i)
if (!egl_texture_map(texture, i))
return false;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
return true;
}
static void egl_texture_unmap(EGL_Texture * texture, uint8_t i) static void egl_texture_unmap(EGL_Texture * texture, uint8_t i)
{ {
if (!texture->tex[i].map) if (!texture->tex[i].map)
@ -162,25 +153,35 @@ static void egl_texture_unmap(EGL_Texture * texture, uint8_t i)
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->tex[i].pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, texture->tex[i].pbo);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
texture->tex[i].map = NULL; texture->tex[i].map = NULL;
} }
static void egl_texture_unmap_all(EGL_Texture * texture)
{
for(int i = 0; i < TEXTURE_COUNT; ++i)
egl_texture_unmap(texture, i);
}
bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_t width, size_t height, size_t stride, bool streaming) bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_t width, size_t height, size_t stride, bool streaming)
{ {
int planeCount; int planeCount;
if (texture->streaming)
{
for(int i = 0; i < texture->textureCount; ++i)
{
egl_texture_unmap(texture, i);
if (texture->tex[i].hasPBO)
{
glDeleteBuffers(1, &texture->tex[i].pbo);
texture->tex[i].hasPBO = false;
}
}
}
texture->pixFmt = pixFmt; texture->pixFmt = pixFmt;
texture->width = width; texture->width = width;
texture->height = height; texture->height = height;
texture->stride = stride; texture->stride = stride;
texture->streaming = streaming; texture->streaming = streaming;
texture->textureCount = streaming ? TEXTURE_COUNT : 1;
texture->ready = false; texture->ready = false;
atomic_store_explicit(&texture->state.v, 0, memory_order_relaxed); atomic_store_explicit(&texture->state.v, 0, memory_order_relaxed);
switch(pixFmt) switch(pixFmt)
@ -254,7 +255,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
if (texture->planeCount > 0) if (texture->planeCount > 0)
glDeleteSamplers(texture->planeCount, texture->samplers); glDeleteSamplers(texture->planeCount, texture->samplers);
for(int i = 0; i < TEXTURE_COUNT; ++i) for(int i = 0; i < texture->textureCount; ++i)
{ {
if (texture->planeCount > 0) if (texture->planeCount > 0)
glDeleteTextures(texture->planeCount, texture->tex[i].t); glDeleteTextures(texture->planeCount, texture->tex[i].t);
@ -273,7 +274,7 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
texture->planeCount = planeCount; texture->planeCount = planeCount;
} }
for(int i = 0; i < (streaming ? TEXTURE_COUNT : 1); ++i) for(int i = 0; i < texture->textureCount; ++i)
{ {
for(int p = 0; p < planeCount; ++p) for(int p = 0; p < planeCount; ++p)
{ {
@ -284,14 +285,11 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
} }
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
egl_texture_unmap_all(texture); if (!streaming)
return true;
// release old PBOs and delete and re-create the buffers for(int i = 0; i < texture->textureCount; ++i)
for(int i = 0; i < TEXTURE_COUNT; ++i)
{ {
if (texture->tex[i].hasPBO)
glDeleteBuffers(1, &texture->tex[i].pbo);
glGenBuffers(1, &texture->tex[i].pbo); glGenBuffers(1, &texture->tex[i].pbo);
texture->tex[i].hasPBO = true; texture->tex[i].hasPBO = true;
@ -302,10 +300,10 @@ bool egl_texture_setup(EGL_Texture * texture, enum EGL_PixelFormat pixFmt, size_
NULL, NULL,
GL_MAP_WRITE_BIT GL_MAP_WRITE_BIT
); );
}
if (!egl_texture_map_all(texture)) if (!egl_texture_map(texture, i))
return false; return false;
}
return true; return true;
} }
@ -343,7 +341,6 @@ bool egl_texture_update(EGL_Texture * texture, const uint8_t * buffer)
else else
{ {
/* Non streaming, this is NOT thread safe */ /* Non streaming, this is NOT thread safe */
for(int p = 0; p < texture->planeCount; ++p) for(int p = 0; p < texture->planeCount; ++p)
{ {
glBindTexture(GL_TEXTURE_2D, texture->tex[0].t[p]); glBindTexture(GL_TEXTURE_2D, texture->tex[0].t[p]);
@ -408,6 +405,7 @@ enum EGL_TexStatus egl_texture_process(EGL_Texture * texture)
texture->format, texture->dataType, (const void *)texture->offsets[p]); texture->format, texture->dataType, (const void *)texture->offsets[p]);
} }
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
/* create a fence to prevent usage before the update is complete */ /* create a fence to prevent usage before the update is complete */
texture->tex[s.u].sync = texture->tex[s.u].sync =
@ -419,8 +417,8 @@ enum EGL_TexStatus egl_texture_process(EGL_Texture * texture)
texture->ready = true; texture->ready = true;
atomic_store_explicit(&texture->state.u, nextu, memory_order_release); atomic_store_explicit(&texture->state.u, nextu, memory_order_release);
/* remap the for the next update */ if (!egl_texture_map(texture, s.u))
egl_texture_map(texture, s.u); return EGL_TEX_STATUS_ERROR;
return EGL_TEX_STATUS_OK; return EGL_TEX_STATUS_OK;
} }