[Mesa-dev] [PATCH] egl: deduplicate allocations of local buffer over each platform backend.
Emil Velikov
emil.l.velikov at gmail.com
Thu Aug 3 12:48:10 UTC 2017
Hi Gwan-gyeong Mun,
Thanks for sorting this out. Having a single copy instead of 3+ is always a win.
On 2 August 2017 at 10:23, Gwan-gyeong Mun <elongbug at gmail.com> wrote:
> platform_drm, platform_wayland and platform_android have similiar local buffer
> allocation routines. For deduplicating, it unifies dri2_egl_surface's
> local buffer allocation routines. And it polishes inconsistent indentations.
>
> Signed-off-by: Mun Gwan-gyeong <elongbug at gmail.com>
> ---
> src/egl/drivers/dri2/egl_dri2.c | 40 ++++++++++++++++++++
> src/egl/drivers/dri2/egl_dri2.h | 16 ++++++--
> src/egl/drivers/dri2/platform_android.c | 40 ++------------------
> src/egl/drivers/dri2/platform_drm.c | 65 +++++++++++----------------------
> src/egl/drivers/dri2/platform_wayland.c | 52 ++++++--------------------
> 5 files changed, 89 insertions(+), 124 deletions(-)
>
> diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
> index a197e0456f..6ee3b36739 100644
> --- a/src/egl/drivers/dri2/egl_dri2.c
> +++ b/src/egl/drivers/dri2/egl_dri2.c
> @@ -972,6 +972,46 @@ dri2_display_destroy(_EGLDisplay *disp)
> disp->DriverData = NULL;
> }
>
> +__DRIbuffer *
> +dri2_egl_surface_alloc_local_buffer(struct dri2_egl_surface *dri2_surf,
> + unsigned int att, unsigned int format)
> +{
> +#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || defined(HAVE_ANDROID_PLATFORM)
I think we can make this unconditional - a few bytes of extra code [in
the corner case], should be that bad.
[...]
> +void
> +dri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf)
> +{
> +#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || defined(HAVE_ANDROID_PLATFORM)
Ditto.
[...]
> +#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || defined(HAVE_ANDROID_PLATFORM)
> + /* EGL-owned buffers */
> + __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT];
> +#endif
> +
... and here.
[...]
> static __DRIbuffer *
> dri2_drm_get_buffers_with_format(__DRIdrawable *driDrawable,
> - int *width, int *height,
> - unsigned int *attachments, int count,
> - int *out_count, void *loaderPrivate)
> + int *width, int *height,
> + unsigned int *attachments, int count,
> + int *out_count, void *loaderPrivate)
> {
> struct dri2_egl_surface *dri2_surf = loaderPrivate;
> int i, j;
>
> for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
> + __DRIbuffer *local;
> +
> assert(attachments[i] < __DRI_BUFFER_COUNT);
> assert(j < ARRAY_SIZE(dri2_surf->buffers));
>
> switch (attachments[i]) {
> case __DRI_BUFFER_BACK_LEFT:
> - if (get_back_bo(dri2_surf) < 0) {
> - _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
> - return NULL;
> - }
> + if (get_back_bo(dri2_surf) < 0) {
> + _eglError(EGL_BAD_ALLOC, "failed to allocate color buffer");
> + return NULL;
> + }
> back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
> - break;
> + break;
Unrelated whitespace changes?
> default:
> - if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
> - &dri2_surf->buffers[j]) < 0) {
> - _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
> - return NULL;
> - }
> - break;
> + local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
> + attachments[i + 1]);
> +
> + if (local)
> + dri2_surf->buffers[j] = *local;
> + else {
> + _eglError(EGL_BAD_ALLOC, "failed to allocate local buffer");
> + return NULL;
> + }
Please preserve the original codeflow:
if (condition) {
error_path
return
}
normal_path
[...]
> --- a/src/egl/drivers/dri2/platform_wayland.c
> +++ b/src/egl/drivers/dri2/platform_wayland.c
> @@ -287,13 +287,8 @@ dri2_wl_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
> dri2_surf->color_buffers[i].data_size);
> }
>
> - if (dri2_dpy->dri2) {
> - for (int i = 0; i < __DRI_BUFFER_COUNT; i++)
> - if (dri2_surf->dri_buffers[i] &&
> - dri2_surf->dri_buffers[i]->attachment != __DRI_BUFFER_BACK_LEFT)
> - dri2_dpy->dri2->releaseBuffer(dri2_dpy->dri_screen,
> - dri2_surf->dri_buffers[i]);
> - }
> + if (dri2_dpy->dri2)
> + dri2_egl_surface_free_local_buffers(dri2_surf);
This seems like a functionality change, since the new helper is
missing the __DRI_BUFFER_BACK_LEFT check.
In reality that should not cause issues, since
dri2_wl_get_buffers_with_format() makes sure we don't have such buffer
in local_buffers.
Other platforms are more relaxed - missing the check all togethre.
Tl;Dr; Things should be fine, but elaborate why/how in the commit message.
Thinking out loud:
How can we ensure nobody overflows dri2_surf->buffers[], should we bother?
[...]
> return NULL;
>
> for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
> + __DRIbuffer *local;
Add blank line.
> switch (attachments[i]) {
> case __DRI_BUFFER_BACK_LEFT:
> back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
> break;
> default:
> - if (get_aux_bo(dri2_surf, attachments[i], attachments[i + 1],
> - &dri2_surf->buffers[j]) < 0) {
> - _eglError(EGL_BAD_ALLOC, "failed to allocate aux buffer");
> + local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
> + attachments[i + 1]);
> +
> + if (local)
> + dri2_surf->buffers[j] = *local;
> + else {
> + _eglError(EGL_BAD_ALLOC, "failed to allocate local buffer");
Please preserve original codeflow.
With the above addressed the patch is
Reviewed-by: Emil Velikov <emil.velikov at collabora.com>
Thanks
Emil
More information about the mesa-dev
mailing list