-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Looks good to me.
Am 2014-02-13 13:05, schrieb Martin Storsjo:
--- Fixed the final style issues and added comments about who activates the GL context. --- dlls/wined3d/arb_program_shader.c | 204 +++++++++++++++++++++++++------------- 1 file changed, 134 insertions(+), 70 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 93a6e31..a273eac 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -6768,22 +6768,74 @@ const struct fragment_pipeline arbfp_fragment_pipeline = { arbfp_fragmentstate_template, };
-struct arbfp_blit_priv { - GLenum yuy2_rect_shader, yuy2_2d_shader; - GLenum uyvy_rect_shader, uyvy_2d_shader; - GLenum yv12_rect_shader, yv12_2d_shader; - GLenum nv12_rect_shader, nv12_2d_shader; - GLenum p8_rect_shader, p8_2d_shader; +struct arbfp_blit_type +{ + enum complex_fixup fixup; + GLenum textype; +}; + +struct arbfp_blit_desc +{ + GLenum shader; + struct arbfp_blit_type type; + struct wine_rb_entry entry; +}; + +struct arbfp_blit_priv +{ + struct wine_rb_tree shaders; GLuint palette_texture; };
+static int arbfp_blit_type_compare(const void *key, const struct wine_rb_entry *entry) +{ + const struct arbfp_blit_type *ka = key; + const struct arbfp_blit_type *kb = &WINE_RB_ENTRY_VALUE(entry, const struct arbfp_blit_desc, entry)->type; + + if (ka->fixup != kb->fixup) + return ka->fixup < kb->fixup ? -1 : 1; + if (ka->textype != kb->textype) + return ka->textype < kb->textype ? -1 : 1; + return 0; +} + +/* Context activation is done by the caller. */ +static void arbfp_free_blit_shader(struct wine_rb_entry *entry, void *context) +{ + const struct wined3d_gl_info *gl_info = context; + struct arbfp_blit_desc *entry_arb = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); + + GL_EXTCALL(glDeleteProgramsARB(1, &entry_arb->shader)); + checkGLcall("glDeleteProgramsARB(1, &entry_arb->shader)"); + HeapFree(GetProcessHeap(), 0, entry_arb); +} + +const struct wine_rb_functions wined3d_arbfp_blit_rb_functions = +{ + wined3d_rb_alloc, + wined3d_rb_realloc, + wined3d_rb_free, + arbfp_blit_type_compare, +}; + static HRESULT arbfp_blit_alloc(struct wined3d_device *device) { + struct arbfp_blit_priv *priv; device->blit_priv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct arbfp_blit_priv)); if(!device->blit_priv) { ERR("Out of memory\n"); return E_OUTOFMEMORY; } + priv = device->blit_priv;
- if (wine_rb_init(&priv->shaders,
&wined3d_arbfp_blit_rb_functions) == -1) + { + ERR("Failed to initialize rbtree.\n"); + HeapFree(GetProcessHeap(), 0, device->blit_priv); + device->blit_priv = NULL; + return E_OUTOFMEMORY; + } + return WINED3D_OK; }
@@ -6793,17 +6845,8 @@ static void arbfp_blit_free(struct wined3d_device *device) const struct wined3d_gl_info *gl_info = &device->adapter->gl_info; struct arbfp_blit_priv *priv = device->blit_priv;
- GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_rect_shader)); -
GL_EXTCALL(glDeleteProgramsARB(1, &priv->yuy2_2d_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_rect_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->uyvy_2d_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_rect_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->yv12_2d_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->nv12_rect_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->nv12_2d_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_rect_shader)); - GL_EXTCALL(glDeleteProgramsARB(1, &priv->p8_2d_shader)); - checkGLcall("Delete yuv and p8 programs"); + wine_rb_destroy(&priv->shaders, arbfp_free_blit_shader, &device->adapter->gl_info); + checkGLcall("Delete blit programs");
if (priv->palette_texture) gl_info->gl_ops.gl.p_glDeleteTextures(1, &priv->palette_texture); @@ -7196,12 +7239,14 @@ static BOOL gen_nv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, return TRUE; }
+/* Context activation is done by the caller. */ static GLuint gen_p8_shader(struct arbfp_blit_priv *priv, const struct wined3d_gl_info *gl_info, GLenum textype) { GLenum shader; struct wined3d_shader_buffer buffer; GLint pos; + struct arbfp_blit_desc *desc;
/* Shader header */ if (!shader_buffer_init(&buffer)) @@ -7249,14 +7294,34 @@ static GLuint gen_p8_shader(struct arbfp_blit_priv *priv, shader_arb_dump_program_source(buffer.buffer); }
- if (textype == GL_TEXTURE_RECTANGLE_ARB) -
priv->p8_rect_shader = shader; - else - priv->p8_2d_shader = shader; - shader_buffer_free(&buffer);
- desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc)); + if
(!desc) + { + ERR("Out of memory\n"); + goto err_out; + } + + desc->type.textype = textype; + desc->type.fixup = COMPLEX_FIXUP_P8; + desc->shader = shader; + if (wine_rb_put(&priv->shaders, &desc->type, &desc->entry) == -1) + { + ERR("Out of memory\n"); + goto err_out; + } + return shader; + +err_out: + GL_EXTCALL(glDeleteProgramsARB(1, &shader)); + checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader))"); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); + checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)"); + if (desc) + HeapFree(GetProcessHeap(), 0, desc); + return 0; }
/* Context activation is done by the caller. */ @@ -7298,6 +7363,7 @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_ struct wined3d_shader_buffer buffer; char luminance_component; GLint pos; + struct arbfp_blit_desc *desc;
/* Shader header */ if (!shader_buffer_init(&buffer)) @@ -7428,34 +7494,32 @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_
shader_buffer_free(&buffer);
- switch (yuv_fixup) + desc = HeapAlloc(GetProcessHeap(), 0,
sizeof(*desc)); + if (!desc) { - case COMPLEX_FIXUP_YUY2: - if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yuy2_rect_shader = shader; - else priv->yuy2_2d_shader = shader; - break; - - case COMPLEX_FIXUP_UYVY: - if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->uyvy_rect_shader = shader; - else priv->uyvy_2d_shader = shader; - break; - - case COMPLEX_FIXUP_YV12: - if (textype == GL_TEXTURE_RECTANGLE_ARB) priv->yv12_rect_shader = shader; - else priv->yv12_2d_shader = shader; - break; + ERR("Out of memory\n"); + goto err_out; + }
case COMPLEX_FIXUP_NV12: - if (textype ==
GL_TEXTURE_RECTANGLE_ARB) - priv->nv12_rect_shader = shader; - else - priv->nv12_2d_shader = shader; - break; - default: - ERR("Unsupported complex fixup: %d\n", yuv_fixup); + desc->type.textype = textype; + desc->type.fixup = yuv_fixup; + desc->shader = shader; + if (wine_rb_put(&priv->shaders, &desc->type, &desc->entry) == -1) + { + ERR("Out of memory\n"); + goto err_out; }
return shader; + +err_out: + GL_EXTCALL(glDeleteProgramsARB(1, &shader)); + checkGLcall("GL_EXTCALL(glDeleteProgramsARB(1, &shader))"); + GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)); + checkGLcall("glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0)"); + if (desc) + HeapFree(GetProcessHeap(), 0, desc); + return 0; }
/* Context activation is done by the caller. */ @@ -7467,6 +7531,8 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context, enum complex_fixup fixup; const struct wined3d_gl_info *gl_info = context->gl_info; GLenum textype = surface->container->target; + struct wine_rb_entry *entry; + struct arbfp_blit_type type;
if (surface->flags & SFLAG_CONVERTED) { @@ -7487,39 +7553,37 @@ static HRESULT arbfp_blit_set(void *blit_priv, struct wined3d_context *context,
fixup = get_complex_fixup(surface->resource.format->color_fixup);
- switch(fixup) + type.fixup = fixup; + type.textype =
textype; + entry = wine_rb_get(&priv->shaders, &type); + if (entry) { - case COMPLEX_FIXUP_YUY2: - shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yuy2_rect_shader : priv->yuy2_2d_shader; - break; - - case COMPLEX_FIXUP_UYVY: - shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->uyvy_rect_shader : priv->uyvy_2d_shader; - break; - - case COMPLEX_FIXUP_YV12: - shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->yv12_rect_shader : priv->yv12_2d_shader; - break; - - case COMPLEX_FIXUP_NV12: - shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->nv12_rect_shader : priv->nv12_2d_shader; - break; - - case COMPLEX_FIXUP_P8: - shader = textype == GL_TEXTURE_RECTANGLE_ARB ? priv->p8_rect_shader : priv->p8_2d_shader; - if (!shader) shader = gen_p8_shader(priv, gl_info, textype); + struct arbfp_blit_desc *desc = WINE_RB_ENTRY_VALUE(entry, struct arbfp_blit_desc, entry); + shader = desc->shader; + } + else + { + switch (fixup) + { + case COMPLEX_FIXUP_P8: + shader = gen_p8_shader(priv, gl_info, textype); + break;
upload_palette(surface, context); - break;
default: + shader =
gen_yuv_shader(priv, gl_info, fixup, textype); + break; + }
default: + if (!shader) + {
FIXME("Unsupported complex fixup %#x, not setting a shader\n", fixup); gl_info->gl_ops.gl.p_glEnable(textype); checkGLcall("glEnable(textype)"); return E_NOTIMPL; + } } -
- if (!shader) shader = gen_yuv_shader(priv, gl_info, fixup,
textype); + if (fixup == COMPLEX_FIXUP_P8) + upload_palette(surface, context);
gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB); checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB)");