1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26 #include "mix_renderer.h"
27
28 // C header adapter
29 extern "C" {
30 #include "libweston/libweston.h"
31 #include "shared/helpers.h"
32 }
33
34 #include "libweston/trace.h"
35 DEFINE_LOG_LABEL("MixRenderer");
36
37 struct mix_renderer {
38 struct weston_renderer base;
39 };
40
41 static void
mix_renderer_attach(struct weston_surface * surface,struct weston_buffer * buffer)42 mix_renderer_attach(struct weston_surface *surface,
43 struct weston_buffer *buffer)
44 {
45 surface->compositor->hdi_renderer->attach(surface, buffer);
46 if (surface->compositor->gpu_renderer) {
47 surface->compositor->gpu_renderer->attach(surface, buffer);
48 }
49 }
50
51 static void
mix_renderer_destroy(struct weston_compositor * compositor)52 mix_renderer_destroy(struct weston_compositor *compositor)
53 {
54 LOG_PASS();
55 delete reinterpret_cast<struct mix_renderer *>(compositor->renderer);
56 compositor->renderer = NULL;
57
58 if (compositor->gpu_renderer) {
59 compositor->gpu_renderer->destroy(compositor);
60 }
61
62 if (compositor->hdi_renderer) {
63 compositor->hdi_renderer->destroy(compositor);
64 }
65 }
66
67 static void
mix_renderer_flush_damage(struct weston_surface * surface)68 mix_renderer_flush_damage(struct weston_surface *surface)
69 {
70 if (surface->compositor->gpu_renderer) {
71 surface->compositor->gpu_renderer->flush_damage(surface);
72 } else {
73 surface->compositor->hdi_renderer->flush_damage(surface);
74 }
75 }
76
77 static bool
mix_renderer_import_dmabuf(struct weston_compositor * compositor,struct linux_dmabuf_buffer * buffer)78 mix_renderer_import_dmabuf(struct weston_compositor *compositor,
79 struct linux_dmabuf_buffer *buffer)
80 {
81 struct weston_renderer *renderer = compositor->gpu_renderer;
82 if (!renderer) {
83 renderer = compositor->hdi_renderer;
84 }
85
86 if (renderer->import_dmabuf == NULL)
87 return false;
88
89 return renderer->import_dmabuf(compositor, buffer);
90 }
91
92 static void
mix_renderer_query_dmabuf_formats(struct weston_compositor * compositor,int ** formats,int * num_formats)93 mix_renderer_query_dmabuf_formats(struct weston_compositor *compositor,
94 int **formats, int *num_formats)
95 {
96 compositor->hdi_renderer->query_dmabuf_formats(compositor, formats, num_formats);
97 }
98
99 static void
mix_renderer_query_dmabuf_modifiers(struct weston_compositor * compositor,int format,uint64_t ** modifiers,int * num_modifiers)100 mix_renderer_query_dmabuf_modifiers(struct weston_compositor *compositor,
101 int format,
102 uint64_t **modifiers,
103 int *num_modifiers)
104 {
105 compositor->hdi_renderer->query_dmabuf_modifiers(compositor, format, modifiers, num_modifiers);
106 }
107
108 static int
mix_renderer_read_pixels(struct weston_output * output,pixman_format_code_t format,void * pixels,uint32_t x,uint32_t y,uint32_t width,uint32_t height)109 mix_renderer_read_pixels(struct weston_output *output,
110 pixman_format_code_t format, void *pixels,
111 uint32_t x, uint32_t y,
112 uint32_t width, uint32_t height)
113 {
114 return output->compositor->hdi_renderer->read_pixels(output, format, pixels, x, y, width, height);
115 }
116
117 static void
mix_renderer_repaint_output(struct weston_output * output,pixman_region32_t * output_damage)118 mix_renderer_repaint_output(struct weston_output *output,
119 pixman_region32_t *output_damage)
120 {
121 output->compositor->hdi_renderer->repaint_output(output, output_damage);
122 }
123
124 static void
mix_renderer_surface_set_color(struct weston_surface * surface,float red,float green,float blue,float alpha)125 mix_renderer_surface_set_color(struct weston_surface *surface,
126 float red, float green,
127 float blue, float alpha)
128 {
129 if (surface->compositor->gpu_renderer) {
130 surface->compositor->gpu_renderer->surface_set_color(surface, red, green, blue, alpha);
131 } else {
132 surface->compositor->hdi_renderer->surface_set_color(surface, red, green, blue, alpha);
133 }
134 }
135
136 static void
mix_renderer_surface_get_content_size(struct weston_surface * surface,int * width,int * height)137 mix_renderer_surface_get_content_size(struct weston_surface *surface,
138 int *width, int *height)
139 {
140 surface->compositor->hdi_renderer->surface_get_content_size(surface, width, height);
141 }
142
143 static int
mix_renderer_surface_copy_content(struct weston_surface * surface,void * target,size_t size,int src_x,int src_y,int width,int height)144 mix_renderer_surface_copy_content(struct weston_surface *surface,
145 void *target, size_t size,
146 int src_x, int src_y, int width, int height)
147 {
148 return surface->compositor->hdi_renderer->surface_copy_content(surface, target, size,
149 src_x, src_y, width, height);
150 }
151
152 int
mix_renderer_init(struct weston_compositor * compositor)153 mix_renderer_init(struct weston_compositor *compositor)
154 {
155 LOG_PASS();
156 auto renderer = new struct mix_renderer();
157 if (renderer == NULL) {
158 return 1;
159 }
160
161 renderer->base.attach = mix_renderer_attach;
162 renderer->base.destroy = mix_renderer_destroy;
163 renderer->base.flush_damage = mix_renderer_flush_damage;
164 renderer->base.import_dmabuf = mix_renderer_import_dmabuf;
165 renderer->base.query_dmabuf_formats = mix_renderer_query_dmabuf_formats;
166 renderer->base.query_dmabuf_modifiers = mix_renderer_query_dmabuf_modifiers;
167 renderer->base.read_pixels = mix_renderer_read_pixels;
168 renderer->base.repaint_output = mix_renderer_repaint_output;
169 renderer->base.surface_set_color = mix_renderer_surface_set_color;
170 renderer->base.surface_get_content_size = mix_renderer_surface_get_content_size;
171 renderer->base.surface_copy_content = mix_renderer_surface_copy_content;
172
173 compositor->renderer = &renderer->base;
174 return 0;
175 }
176