onscreen/native: Provide damage rectangles to secondary GPUs in copy path
This provides damage rectangles to the secondary GPU in the copy path so it, much like the primary GPU, can avoid updating parts of the framebuffer that haven't been changed since the last frame(s). This works in tandem with EGL_EXT_buffer_age to determine how old the contents of the current framebuffer are (i.e. to know if there is anything to reuse from the last frame). (cherry picked from commit bf4a767ac3a36eac7a2fc612550a218ebfb9480d) Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4073> Signed-off-by: Mingi Sung <sungmg@saltyming.net>
This commit is contained in:
parent
443366ede5
commit
47293a748d
3 changed files with 304 additions and 53 deletions
|
@ -53,6 +53,18 @@
|
|||
#include "common/meta-cogl-drm-formats.h"
|
||||
#include "common/meta-drm-format-helpers.h"
|
||||
|
||||
/*
|
||||
The maximum amount of damage rectangles to maintain. At a certain point there are so many damage rectangles that
|
||||
individually processing them isn't worth the time they save based on a full redraw, which is determined by this
|
||||
number.
|
||||
*/
|
||||
#define MAX_DAMAGE_RECTANGLES 16
|
||||
|
||||
/*
|
||||
The maximum supported buffer age for secondary GPU surfaces.
|
||||
*/
|
||||
#define MAX_SECONDARY_GPU_BUFFER_AGE 4
|
||||
|
||||
typedef enum _MetaSharedFramebufferImportStatus
|
||||
{
|
||||
/* Not tried importing yet. */
|
||||
|
@ -63,6 +75,12 @@ typedef enum _MetaSharedFramebufferImportStatus
|
|||
META_SHARED_FRAMEBUFFER_IMPORT_STATUS_OK
|
||||
} MetaSharedFramebufferImportStatus;
|
||||
|
||||
typedef struct _MetaOnscreenNativeSecondaryGpuDamageRectangleInfo
|
||||
{
|
||||
MtkRectangle rectangles[MAX_DAMAGE_RECTANGLES];
|
||||
int n_rectangles;
|
||||
} MetaOnscreenNativeSecondaryGpuDamageRectangleInfo;
|
||||
|
||||
typedef struct _MetaOnscreenNativeSecondaryGpuState
|
||||
{
|
||||
MetaGpuKms *gpu_kms;
|
||||
|
@ -79,6 +97,8 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
|
|||
MetaDrmBufferDumb *dumb_fbs[2];
|
||||
} cpu;
|
||||
|
||||
MetaOnscreenNativeSecondaryGpuDamageRectangleInfo damage_rectangles[MAX_SECONDARY_GPU_BUFFER_AGE];
|
||||
|
||||
gboolean noted_primary_gpu_copy_ok;
|
||||
gboolean noted_primary_gpu_copy_failed;
|
||||
MetaSharedFramebufferImportStatus import_status;
|
||||
|
@ -831,11 +851,94 @@ import_shared_framebuffer (CoglOnscreen *onscreen,
|
|||
return imported_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
push_secondary_gpu_damage_rectangles (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
const int *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (n_rectangles > MAX_DAMAGE_RECTANGLES)
|
||||
n_rectangles = 0;
|
||||
|
||||
for (i = MAX_SECONDARY_GPU_BUFFER_AGE - 1; i > 0; --i)
|
||||
{
|
||||
if (secondary_gpu_state->damage_rectangles[i - 1].n_rectangles > 0)
|
||||
memcpy (secondary_gpu_state->damage_rectangles[i].rectangles,
|
||||
secondary_gpu_state->damage_rectangles[i - 1].rectangles,
|
||||
secondary_gpu_state->damage_rectangles[i - 1].n_rectangles * sizeof (MtkRectangle));
|
||||
|
||||
secondary_gpu_state->damage_rectangles[i].n_rectangles = secondary_gpu_state->damage_rectangles[i - 1].n_rectangles;
|
||||
}
|
||||
|
||||
if (n_rectangles > 0)
|
||||
memcpy (secondary_gpu_state->damage_rectangles[0].rectangles,
|
||||
rectangles,
|
||||
n_rectangles * sizeof (MtkRectangle));
|
||||
|
||||
secondary_gpu_state->damage_rectangles[0].n_rectangles = n_rectangles;
|
||||
}
|
||||
|
||||
static int
|
||||
calculate_secondary_gpu_damage_rectangle_count (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
int buffer_age)
|
||||
{
|
||||
int i;
|
||||
int union_n_rectangles = 0;
|
||||
|
||||
for (i = 0; i <= buffer_age; ++i)
|
||||
{
|
||||
/* Everything being damaged in a previous frame means we also need to damage everything now. */
|
||||
if (secondary_gpu_state->damage_rectangles[i].n_rectangles == 0)
|
||||
return 0;
|
||||
|
||||
union_n_rectangles += secondary_gpu_state->damage_rectangles[i].n_rectangles;
|
||||
}
|
||||
|
||||
return union_n_rectangles;
|
||||
}
|
||||
|
||||
static int
|
||||
get_secondary_gpu_buffer_age (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
MetaRendererNativeGpuData *renderer_gpu_data)
|
||||
{
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||
MetaRenderDevice *render_device;
|
||||
EGLDisplay egl_display;
|
||||
int buffer_age;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
render_device = renderer_gpu_data->render_device;
|
||||
egl_display = meta_render_device_get_egl_display (render_device);
|
||||
|
||||
if (!meta_egl_query_surface (egl, egl_display, secondary_gpu_state->egl_surface, EGL_BUFFER_AGE_EXT, &buffer_age, &error))
|
||||
{
|
||||
g_warning ("Failed to query age of surface, ignoring damage rectangles and fully redrawing, "
|
||||
"which may cause increased GPU power consumption: %s", error->message);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (buffer_age > MAX_SECONDARY_GPU_BUFFER_AGE)
|
||||
{
|
||||
g_warning ("Secondary GPU provides buffers of age %i, which is older than supported; "
|
||||
"ignoring damage rectangles and fully redrawing which may cause incraesed GPU power consumption",
|
||||
buffer_age);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return buffer_age;
|
||||
}
|
||||
|
||||
static MetaDrmBuffer *
|
||||
copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state,
|
||||
MetaRendererNativeGpuData *renderer_gpu_data,
|
||||
MetaDrmBuffer *primary_gpu_fb,
|
||||
const int *rectangles,
|
||||
int n_rectangles,
|
||||
GError **error)
|
||||
{
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
|
@ -851,10 +954,15 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
MetaDrmBufferFlags flags;
|
||||
MetaDrmBufferGbm *buffer_gbm = NULL;
|
||||
struct gbm_bo *bo;
|
||||
int buffer_age = 0;
|
||||
int blit_n_rectangles = 0;
|
||||
MtkRectangle *blit_rectangles = NULL;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferSecondaryGpu,
|
||||
"copy_shared_framebuffer_gpu()");
|
||||
|
||||
push_secondary_gpu_damage_rectangles (secondary_gpu_state, rectangles, n_rectangles);
|
||||
|
||||
if (renderer_gpu_data->secondary.needs_explicit_sync)
|
||||
cogl_framebuffer_finish (COGL_FRAMEBUFFER (onscreen));
|
||||
|
||||
|
@ -874,12 +982,35 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
|||
|
||||
buffer_gbm = META_DRM_BUFFER_GBM (primary_gpu_fb);
|
||||
bo = meta_drm_buffer_gbm_get_bo (buffer_gbm);
|
||||
|
||||
buffer_age = get_secondary_gpu_buffer_age (secondary_gpu_state, renderer_gpu_data);
|
||||
blit_n_rectangles = calculate_secondary_gpu_damage_rectangle_count (secondary_gpu_state, buffer_age);
|
||||
|
||||
if (blit_n_rectangles > 0)
|
||||
{
|
||||
int i;
|
||||
size_t offset = 0;
|
||||
|
||||
blit_rectangles = g_newa (MtkRectangle, blit_n_rectangles);
|
||||
|
||||
for (i = 0; i <= buffer_age; ++i)
|
||||
{
|
||||
memcpy (blit_rectangles + offset,
|
||||
secondary_gpu_state->damage_rectangles[i].rectangles,
|
||||
secondary_gpu_state->damage_rectangles[i].n_rectangles * sizeof(MtkRectangle));
|
||||
|
||||
offset += secondary_gpu_state->damage_rectangles[i].n_rectangles;
|
||||
}
|
||||
}
|
||||
|
||||
if (!meta_renderer_native_gles3_blit_shared_bo (egl,
|
||||
gles3,
|
||||
egl_display,
|
||||
renderer_gpu_data->secondary.egl_context,
|
||||
secondary_gpu_state->egl_surface,
|
||||
bo,
|
||||
blit_rectangles,
|
||||
blit_n_rectangles,
|
||||
error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to blit shared framebuffer: ");
|
||||
|
@ -1009,10 +1140,8 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
|||
error->message);
|
||||
return NULL;
|
||||
}
|
||||
/* Limit the number of individual copies to 16 */
|
||||
#define MAX_RECTS 16
|
||||
|
||||
if (n_rectangles == 0 || n_rectangles > MAX_RECTS)
|
||||
if (n_rectangles == 0 || n_rectangles > MAX_DAMAGE_RECTANGLES)
|
||||
{
|
||||
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
|
||||
0, 0, 0, 0,
|
||||
|
@ -1177,6 +1306,8 @@ static MetaDrmBuffer *
|
|||
acquire_front_buffer (CoglOnscreen *onscreen,
|
||||
MetaDrmBuffer *primary_gpu_fb,
|
||||
MetaDrmBuffer *secondary_gpu_fb,
|
||||
const int *rectangles,
|
||||
int n_rectangles,
|
||||
GError **error)
|
||||
{
|
||||
MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
|
||||
|
@ -1222,6 +1353,8 @@ acquire_front_buffer (CoglOnscreen *onscreen,
|
|||
secondary_gpu_state,
|
||||
renderer_gpu_data,
|
||||
primary_gpu_fb,
|
||||
rectangles,
|
||||
n_rectangles,
|
||||
error);
|
||||
}
|
||||
|
||||
|
@ -1377,6 +1510,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||
buffer = acquire_front_buffer (onscreen,
|
||||
primary_gpu_fb,
|
||||
secondary_gpu_fb,
|
||||
rectangles,
|
||||
n_rectangles,
|
||||
&error);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
|
|
|
@ -196,11 +196,13 @@ ensure_shader_program (ContextData *context_data,
|
|||
"attribute vec2 position;\n"
|
||||
"attribute vec2 texcoord;\n"
|
||||
"varying vec2 v_texcoord;\n"
|
||||
"uniform float framebuffer_width;\n"
|
||||
"uniform float framebuffer_height;\n"
|
||||
"\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(position, 0.0, 1.0);\n"
|
||||
" v_texcoord = texcoord;\n"
|
||||
" gl_Position = vec4(position.x / framebuffer_width * 2.0 - 1.0, position.y / framebuffer_height * 2.0 - 1.0, 0.0, 1.0);\n"
|
||||
" v_texcoord = vec2(texcoord.x / framebuffer_width, texcoord.y / framebuffer_height);\n"
|
||||
"}\n";
|
||||
|
||||
static const char fragment_shader_source[] =
|
||||
|
@ -215,16 +217,8 @@ ensure_shader_program (ContextData *context_data,
|
|||
" gl_FragColor = texture2D(s_texture, v_texcoord);\n"
|
||||
"}\n";
|
||||
|
||||
static const GLfloat box[] =
|
||||
{ /* position texcoord */
|
||||
-1.0f, +1.0f, 0.0f, 0.0f,
|
||||
+1.0f, +1.0f, 1.0f, 0.0f,
|
||||
+1.0f, -1.0f, 1.0f, 1.0f,
|
||||
-1.0f, -1.0f, 0.0f, 1.0f,
|
||||
};
|
||||
GLint linked;
|
||||
GLuint vertex_shader, fragment_shader;
|
||||
GLint position_attrib, texcoord_attrib;
|
||||
GLuint shader_program;
|
||||
|
||||
if (context_data->shader_program)
|
||||
|
@ -254,23 +248,15 @@ ensure_shader_program (ContextData *context_data,
|
|||
}
|
||||
|
||||
GLBAS (gles3, glUseProgram, (shader_program));
|
||||
|
||||
position_attrib = glGetAttribLocation (shader_program, "position");
|
||||
GLBAS (gles3, glEnableVertexAttribArray, (position_attrib));
|
||||
GLBAS (gles3, glVertexAttribPointer,
|
||||
(position_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box));
|
||||
|
||||
texcoord_attrib = glGetAttribLocation (shader_program, "texcoord");
|
||||
GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib));
|
||||
GLBAS (gles3, glVertexAttribPointer,
|
||||
(texcoord_attrib, 2, GL_FLOAT, GL_FALSE, 4 * sizeof (GLfloat), box + 2));
|
||||
}
|
||||
|
||||
static void
|
||||
blit_egl_image (MetaGles3 *gles3,
|
||||
EGLImageKHR egl_image,
|
||||
int width,
|
||||
int height)
|
||||
blit_egl_image (MetaGles3 *gles3,
|
||||
EGLImageKHR egl_image,
|
||||
int width,
|
||||
int height,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
GLuint texture;
|
||||
GLuint framebuffer;
|
||||
|
@ -301,29 +287,152 @@ blit_egl_image (MetaGles3 *gles3,
|
|||
GL_TEXTURE_2D, texture, 0));
|
||||
|
||||
GLBAS (gles3, glBindFramebuffer, (GL_READ_FRAMEBUFFER, framebuffer));
|
||||
GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0,
|
||||
0, 0, width, height,
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST));
|
||||
|
||||
if (n_rectangles > 0)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n_rectangles; ++i)
|
||||
{
|
||||
GLint x1 = rectangles[i].x;
|
||||
GLint y1 = height - rectangles[i].y - rectangles[i].height;
|
||||
GLint src_y1 = rectangles[i].y;
|
||||
GLint x2 = x1 + rectangles[i].width;
|
||||
GLint y2 = y1 + rectangles[i].height;
|
||||
GLint src_y2 = src_y1 + rectangles[i].height;
|
||||
|
||||
GLBAS (gles3, glBlitFramebuffer, (x1, src_y2, x2, src_y1,
|
||||
x1, height - rectangles[i].y - rectangles[i].height, x2, y2,
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST));
|
||||
}
|
||||
}
|
||||
else
|
||||
GLBAS (gles3, glBlitFramebuffer, (0, height, width, 0,
|
||||
0, 0, width, height,
|
||||
GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST));
|
||||
|
||||
|
||||
GLBAS (gles3, glDeleteTextures, (1, &texture));
|
||||
GLBAS (gles3, glDeleteFramebuffers, (1, &framebuffer));
|
||||
}
|
||||
|
||||
static void
|
||||
paint_egl_image (ContextData *context_data,
|
||||
MetaGles3 *gles3,
|
||||
EGLImageKHR egl_image,
|
||||
int width,
|
||||
int height)
|
||||
paint_egl_image (ContextData *context_data,
|
||||
MetaGles3 *gles3,
|
||||
EGLImageKHR egl_image,
|
||||
int width,
|
||||
int height,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles)
|
||||
{
|
||||
static const uint triangle_count_per_rectangle = 2;
|
||||
static const uint vertex_per_triangle = 3;
|
||||
static const uint values_per_vertex = 4;
|
||||
|
||||
const MtkRectangle full_damage_rectangle = {0, 0, width, height};
|
||||
|
||||
int i;
|
||||
GLuint texture;
|
||||
GLint *vertices = NULL;
|
||||
GLuint vertex_buffer_object;
|
||||
GLuint vertex_array_object;
|
||||
GLint position_attrib, texcoord_attrib;
|
||||
GLint framebuffer_width_uniform, framebuffer_height_uniform;
|
||||
GLuint components_per_rectangle = triangle_count_per_rectangle * vertex_per_triangle * values_per_vertex;
|
||||
GLuint size_per_rectangle = components_per_rectangle * sizeof(GLint);
|
||||
GLuint vertices_size;
|
||||
|
||||
if (n_rectangles == 0)
|
||||
{
|
||||
n_rectangles = 1;
|
||||
rectangles = &full_damage_rectangle;
|
||||
}
|
||||
|
||||
vertices_size = n_rectangles * size_per_rectangle;
|
||||
|
||||
vertices = g_alloca (vertices_size);
|
||||
|
||||
for (i = 0; i < n_rectangles; ++i)
|
||||
{
|
||||
const MtkRectangle *rectangle = &rectangles[i];
|
||||
GLint *rectangle_vertices = &vertices[i * components_per_rectangle];
|
||||
|
||||
int reversed_rect_y = height - rectangles[i].y - rectangles[i].height;
|
||||
|
||||
GLint x1 = rectangle->x;
|
||||
GLint y1 = reversed_rect_y;
|
||||
GLint x2 = rectangle->x + rectangle->width;
|
||||
GLint y2 = reversed_rect_y + rectangle->height;
|
||||
|
||||
GLint u1 = rectangle->x;
|
||||
GLint v1 = rectangle->y;
|
||||
GLint u2 = rectangle->x + rectangle->width;
|
||||
GLint v2 = rectangle->y + rectangle->height;
|
||||
|
||||
rectangle_vertices[0] = x1;
|
||||
rectangle_vertices[1] = y2;
|
||||
rectangle_vertices[2] = u1;
|
||||
rectangle_vertices[3] = v1;
|
||||
|
||||
rectangle_vertices[4] = x2;
|
||||
rectangle_vertices[5] = y2;
|
||||
rectangle_vertices[6] = u2;
|
||||
rectangle_vertices[7] = v1;
|
||||
|
||||
rectangle_vertices[8] = x1;
|
||||
rectangle_vertices[9] = y1;
|
||||
rectangle_vertices[10] = u1;
|
||||
rectangle_vertices[11] = v2;
|
||||
|
||||
rectangle_vertices[12] = x1;
|
||||
rectangle_vertices[13] = y1;
|
||||
rectangle_vertices[14] = u1;
|
||||
rectangle_vertices[15] = v2;
|
||||
|
||||
rectangle_vertices[16] = x2;
|
||||
rectangle_vertices[17] = y2;
|
||||
rectangle_vertices[18] = u2;
|
||||
rectangle_vertices[19] = v1;
|
||||
|
||||
rectangle_vertices[20] = x2;
|
||||
rectangle_vertices[21] = y1;
|
||||
rectangle_vertices[22] = u2;
|
||||
rectangle_vertices[23] = v2;
|
||||
}
|
||||
|
||||
meta_gles3_clear_error (gles3);
|
||||
ensure_shader_program (context_data, gles3);
|
||||
|
||||
g_return_if_fail (context_data->shader_program);
|
||||
|
||||
GLBAS (gles3, glViewport, (0, 0, width, height));
|
||||
|
||||
GLBAS (gles3, glGenVertexArrays, (1, &vertex_array_object));
|
||||
GLBAS (gles3, glBindVertexArray, (vertex_array_object));
|
||||
|
||||
GLBAS (gles3, glGenBuffers, (1, &vertex_buffer_object));
|
||||
GLBAS (gles3, glBindBuffer, (GL_ARRAY_BUFFER, vertex_buffer_object));
|
||||
GLBAS (gles3, glBufferData,
|
||||
(GL_ARRAY_BUFFER, vertices_size, vertices, GL_DYNAMIC_DRAW));
|
||||
|
||||
position_attrib = glGetAttribLocation (context_data->shader_program, "position");
|
||||
GLBAS (gles3, glEnableVertexAttribArray, (position_attrib));
|
||||
GLBAS (gles3, glVertexAttribPointer,
|
||||
(position_attrib, 2, GL_INT, GL_FALSE, 4 * sizeof (GLint), NULL));
|
||||
|
||||
texcoord_attrib = glGetAttribLocation (context_data->shader_program, "texcoord");
|
||||
GLBAS (gles3, glEnableVertexAttribArray, (texcoord_attrib));
|
||||
GLBAS (gles3, glVertexAttribPointer,
|
||||
(texcoord_attrib, 2, GL_INT, GL_FALSE, 4 * sizeof (GLint), (void*)(sizeof(GLint) * 2)));
|
||||
|
||||
framebuffer_width_uniform = glGetUniformLocation (context_data->shader_program, "framebuffer_width");
|
||||
GLBAS (gles3, glUniform1f, (framebuffer_width_uniform, width));
|
||||
|
||||
framebuffer_height_uniform = glGetUniformLocation (context_data->shader_program, "framebuffer_height");
|
||||
GLBAS (gles3, glUniform1f, (framebuffer_height_uniform, height));
|
||||
|
||||
GLBAS (gles3, glActiveTexture, (GL_TEXTURE0));
|
||||
GLBAS (gles3, glGenTextures, (1, &texture));
|
||||
GLBAS (gles3, glBindTexture, (GL_TEXTURE_EXTERNAL_OES, texture));
|
||||
|
@ -342,19 +451,23 @@ paint_egl_image (ContextData *context_data,
|
|||
GL_TEXTURE_WRAP_T,
|
||||
GL_CLAMP_TO_EDGE));
|
||||
|
||||
GLBAS (gles3, glDrawArrays, (GL_TRIANGLE_FAN, 0, 4));
|
||||
GLBAS (gles3, glDrawArrays, (GL_TRIANGLES, 0, triangle_count_per_rectangle * vertex_per_triangle * n_rectangles));
|
||||
|
||||
GLBAS (gles3, glDeleteTextures, (1, &texture));
|
||||
GLBAS (gles3, glDeleteBuffers, (1, &vertex_buffer_object));
|
||||
GLBAS (gles3, glDeleteVertexArrays, (1, &vertex_array_object));
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
||||
MetaGles3 *gles3,
|
||||
EGLDisplay egl_display,
|
||||
EGLContext egl_context,
|
||||
EGLSurface egl_surface,
|
||||
struct gbm_bo *shared_bo,
|
||||
GError **error)
|
||||
meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
||||
MetaGles3 *gles3,
|
||||
EGLDisplay egl_display,
|
||||
EGLContext egl_context,
|
||||
EGLSurface egl_surface,
|
||||
struct gbm_bo *shared_bo,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
GError **error)
|
||||
{
|
||||
int shared_bo_fd;
|
||||
unsigned int width;
|
||||
|
@ -435,9 +548,9 @@ meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
|||
return FALSE;
|
||||
|
||||
if (can_blit)
|
||||
blit_egl_image (gles3, egl_image, width, height);
|
||||
blit_egl_image (gles3, egl_image, width, height, rectangles, n_rectangles);
|
||||
else
|
||||
paint_egl_image (context_data, gles3, egl_image, width, height);
|
||||
paint_egl_image (context_data, gles3, egl_image, width, height, rectangles, n_rectangles);
|
||||
|
||||
meta_egl_destroy_image (egl, egl_display, egl_image, NULL);
|
||||
|
||||
|
|
|
@ -25,14 +25,17 @@
|
|||
|
||||
#include "backends/meta-egl.h"
|
||||
#include "backends/meta-gles3.h"
|
||||
#include "mtk/mtk.h"
|
||||
|
||||
gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
||||
MetaGles3 *gles3,
|
||||
EGLDisplay egl_display,
|
||||
EGLContext egl_context,
|
||||
EGLSurface egl_surface,
|
||||
struct gbm_bo *shared_bo,
|
||||
GError **error);
|
||||
gboolean meta_renderer_native_gles3_blit_shared_bo (MetaEgl *egl,
|
||||
MetaGles3 *gles3,
|
||||
EGLDisplay egl_display,
|
||||
EGLContext egl_context,
|
||||
EGLSurface egl_surface,
|
||||
struct gbm_bo *shared_bo,
|
||||
const MtkRectangle *rectangles,
|
||||
int n_rectangles,
|
||||
GError **error);
|
||||
|
||||
void meta_renderer_native_gles3_forget_context (MetaGles3 *gles3,
|
||||
EGLContext egl_context);
|
||||
|
|
Loading…
Reference in a new issue