PaintingCommandExecutorGPU.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibAccelGfx/GlyphAtlas.h>
  7. #include <LibWeb/Painting/PaintingCommandExecutorGPU.h>
  8. namespace Web::Painting {
  9. PaintingCommandExecutorGPU::PaintingCommandExecutorGPU(Gfx::Bitmap& bitmap)
  10. : m_target_bitmap(bitmap)
  11. {
  12. auto painter = AccelGfx::Painter::create();
  13. auto canvas = AccelGfx::Canvas::create(bitmap.size());
  14. painter->set_target_canvas(canvas);
  15. stacking_contexts.append({ .canvas = canvas,
  16. .painter = move(painter),
  17. .opacity = 1.0f,
  18. .destination = {} });
  19. }
  20. PaintingCommandExecutorGPU::~PaintingCommandExecutorGPU()
  21. {
  22. VERIFY(stacking_contexts.size() == 1);
  23. painter().flush(m_target_bitmap);
  24. }
  25. CommandResult PaintingCommandExecutorGPU::draw_glyph_run(Vector<Gfx::DrawGlyphOrEmoji> const& glyph_run, Color const& color)
  26. {
  27. painter().draw_glyph_run(glyph_run, color);
  28. return CommandResult::Continue;
  29. }
  30. CommandResult PaintingCommandExecutorGPU::draw_text(Gfx::IntRect const&, String const&, Gfx::TextAlignment, Color const&, Gfx::TextElision, Gfx::TextWrapping, Optional<NonnullRefPtr<Gfx::Font>> const&)
  31. {
  32. // FIXME
  33. return CommandResult::Continue;
  34. }
  35. CommandResult PaintingCommandExecutorGPU::fill_rect(Gfx::IntRect const& rect, Color const& color)
  36. {
  37. painter().fill_rect(rect, color);
  38. return CommandResult::Continue;
  39. }
  40. static AccelGfx::Painter::ScalingMode to_accelgfx_scaling_mode(Gfx::Painter::ScalingMode scaling_mode)
  41. {
  42. switch (scaling_mode) {
  43. case Gfx::Painter::ScalingMode::NearestNeighbor:
  44. case Gfx::Painter::ScalingMode::BoxSampling:
  45. case Gfx::Painter::ScalingMode::SmoothPixels:
  46. case Gfx::Painter::ScalingMode::None:
  47. return AccelGfx::Painter::ScalingMode::NearestNeighbor;
  48. case Gfx::Painter::ScalingMode::BilinearBlend:
  49. return AccelGfx::Painter::ScalingMode::Bilinear;
  50. default:
  51. VERIFY_NOT_REACHED();
  52. }
  53. }
  54. CommandResult PaintingCommandExecutorGPU::draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode)
  55. {
  56. painter().draw_scaled_bitmap(dst_rect, bitmap, src_rect, to_accelgfx_scaling_mode(scaling_mode));
  57. return CommandResult::Continue;
  58. }
  59. CommandResult PaintingCommandExecutorGPU::draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& immutable_bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode)
  60. {
  61. painter().draw_scaled_immutable_bitmap(dst_rect, immutable_bitmap, src_rect, to_accelgfx_scaling_mode(scaling_mode));
  62. return CommandResult::Continue;
  63. }
  64. CommandResult PaintingCommandExecutorGPU::set_clip_rect(Gfx::IntRect const& rect)
  65. {
  66. painter().set_clip_rect(rect);
  67. return CommandResult::Continue;
  68. }
  69. CommandResult PaintingCommandExecutorGPU::clear_clip_rect()
  70. {
  71. painter().clear_clip_rect();
  72. return CommandResult::Continue;
  73. }
  74. CommandResult PaintingCommandExecutorGPU::set_font(Gfx::Font const&)
  75. {
  76. // FIXME
  77. return CommandResult::Continue;
  78. }
  79. CommandResult PaintingCommandExecutorGPU::push_stacking_context(float opacity, bool is_fixed_position, Gfx::IntRect const& source_paintable_rect, Gfx::IntPoint post_transform_translation, CSS::ImageRendering, StackingContextTransform, Optional<StackingContextMask>)
  80. {
  81. painter().save();
  82. if (is_fixed_position) {
  83. auto const& translation = painter().transform().translation();
  84. painter().translate(-translation);
  85. }
  86. if (opacity < 1) {
  87. auto painter = AccelGfx::Painter::create();
  88. auto canvas = AccelGfx::Canvas::create(source_paintable_rect.size());
  89. painter->set_target_canvas(canvas);
  90. painter->translate(-source_paintable_rect.location().to_type<float>());
  91. stacking_contexts.append({ .canvas = canvas,
  92. .painter = move(painter),
  93. .opacity = opacity,
  94. .destination = source_paintable_rect });
  95. } else {
  96. painter().translate(post_transform_translation.to_type<float>());
  97. }
  98. return CommandResult::Continue;
  99. }
  100. CommandResult PaintingCommandExecutorGPU::pop_stacking_context()
  101. {
  102. if (stacking_contexts.last().opacity < 1) {
  103. auto stacking_context = stacking_contexts.take_last();
  104. painter().blit_canvas(stacking_context.destination, *stacking_context.canvas, stacking_context.opacity);
  105. }
  106. painter().restore();
  107. return CommandResult::Continue;
  108. }
  109. CommandResult PaintingCommandExecutorGPU::paint_linear_gradient(Gfx::IntRect const& rect, Web::Painting::LinearGradientData const& data)
  110. {
  111. painter().fill_rect_with_linear_gradient(rect, data.color_stops.list, data.gradient_angle, data.color_stops.repeat_length);
  112. return CommandResult::Continue;
  113. }
  114. CommandResult PaintingCommandExecutorGPU::paint_outer_box_shadow(PaintOuterBoxShadowParams const&)
  115. {
  116. // FIXME
  117. return CommandResult::Continue;
  118. }
  119. CommandResult PaintingCommandExecutorGPU::paint_inner_box_shadow(PaintOuterBoxShadowParams const&)
  120. {
  121. // FIXME
  122. return CommandResult::Continue;
  123. }
  124. CommandResult PaintingCommandExecutorGPU::paint_text_shadow(int, Gfx::IntRect const&, Gfx::IntRect const&, String const&, Gfx::Font const&, Color const&, int, Gfx::IntPoint const&)
  125. {
  126. // FIXME
  127. return CommandResult::Continue;
  128. }
  129. CommandResult PaintingCommandExecutorGPU::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color const& color, Gfx::AntiAliasingPainter::CornerRadius const& top_left_radius, Gfx::AntiAliasingPainter::CornerRadius const& top_right_radius, Gfx::AntiAliasingPainter::CornerRadius const& bottom_left_radius, Gfx::AntiAliasingPainter::CornerRadius const& bottom_right_radius, Optional<Gfx::FloatPoint> const&)
  130. {
  131. painter().fill_rect_with_rounded_corners(
  132. rect, color,
  133. { static_cast<float>(top_left_radius.horizontal_radius), static_cast<float>(top_left_radius.vertical_radius) },
  134. { static_cast<float>(top_right_radius.horizontal_radius), static_cast<float>(top_right_radius.vertical_radius) },
  135. { static_cast<float>(bottom_left_radius.horizontal_radius), static_cast<float>(bottom_left_radius.vertical_radius) },
  136. { static_cast<float>(bottom_right_radius.horizontal_radius), static_cast<float>(bottom_right_radius.vertical_radius) });
  137. return CommandResult::Continue;
  138. }
  139. CommandResult PaintingCommandExecutorGPU::fill_path_using_color(Gfx::Path const&, Color const&, Gfx::Painter::WindingRule, Optional<Gfx::FloatPoint> const&)
  140. {
  141. // FIXME
  142. return CommandResult::Continue;
  143. }
  144. CommandResult PaintingCommandExecutorGPU::fill_path_using_paint_style(Gfx::Path const&, Gfx::PaintStyle const&, Gfx::Painter::WindingRule, float, Optional<Gfx::FloatPoint> const&)
  145. {
  146. // FIXME
  147. return CommandResult::Continue;
  148. }
  149. CommandResult PaintingCommandExecutorGPU::stroke_path_using_color(Gfx::Path const&, Color const&, float, Optional<Gfx::FloatPoint> const&)
  150. {
  151. // FIXME
  152. return CommandResult::Continue;
  153. }
  154. CommandResult PaintingCommandExecutorGPU::stroke_path_using_paint_style(Gfx::Path const&, Gfx::PaintStyle const&, float, float, Optional<Gfx::FloatPoint> const&)
  155. {
  156. // FIXME
  157. return CommandResult::Continue;
  158. }
  159. CommandResult PaintingCommandExecutorGPU::draw_ellipse(Gfx::IntRect const&, Color const&, int)
  160. {
  161. // FIXME
  162. return CommandResult::Continue;
  163. }
  164. CommandResult PaintingCommandExecutorGPU::fill_ellipse(Gfx::IntRect const& rect, Color const& color, Gfx::AntiAliasingPainter::BlendMode)
  165. {
  166. auto horizontal_radius = static_cast<float>(rect.width() / 2);
  167. auto vertical_radius = static_cast<float>(rect.height() / 2);
  168. painter().fill_rect_with_rounded_corners(
  169. rect, color,
  170. { horizontal_radius, vertical_radius },
  171. { horizontal_radius, vertical_radius },
  172. { horizontal_radius, vertical_radius },
  173. { horizontal_radius, vertical_radius });
  174. return CommandResult::Continue;
  175. }
  176. CommandResult PaintingCommandExecutorGPU::draw_line(Color const& color, Gfx::IntPoint const& a, Gfx::IntPoint const& b, int thickness, Gfx::Painter::LineStyle, Color const&)
  177. {
  178. // FIXME: Pass line style and alternate color once AccelGfx::Painter supports it
  179. painter().draw_line(a, b, thickness, color);
  180. return CommandResult::Continue;
  181. }
  182. CommandResult PaintingCommandExecutorGPU::draw_signed_distance_field(Gfx::IntRect const&, Color const&, Gfx::GrayscaleBitmap const&, float)
  183. {
  184. // FIXME
  185. return CommandResult::Continue;
  186. }
  187. CommandResult PaintingCommandExecutorGPU::paint_progressbar(Gfx::IntRect const&, Gfx::IntRect const&, Palette const&, int, int, int, StringView const&)
  188. {
  189. // FIXME
  190. return CommandResult::Continue;
  191. }
  192. CommandResult PaintingCommandExecutorGPU::paint_frame(Gfx::IntRect const&, Palette const&, Gfx::FrameStyle)
  193. {
  194. // FIXME
  195. return CommandResult::Continue;
  196. }
  197. CommandResult PaintingCommandExecutorGPU::apply_backdrop_filter(Gfx::IntRect const&, Web::CSS::ResolvedBackdropFilter const&)
  198. {
  199. // FIXME
  200. return CommandResult::Continue;
  201. }
  202. CommandResult PaintingCommandExecutorGPU::draw_rect(Gfx::IntRect const&, Color const&, bool)
  203. {
  204. // FIXME
  205. return CommandResult::Continue;
  206. }
  207. CommandResult PaintingCommandExecutorGPU::paint_radial_gradient(Gfx::IntRect const&, Web::Painting::RadialGradientData const&, Gfx::IntPoint const&, Gfx::IntSize const&)
  208. {
  209. // FIXME
  210. return CommandResult::Continue;
  211. }
  212. CommandResult PaintingCommandExecutorGPU::paint_conic_gradient(Gfx::IntRect const&, Web::Painting::ConicGradientData const&, Gfx::IntPoint const&)
  213. {
  214. // FIXME
  215. return CommandResult::Continue;
  216. }
  217. CommandResult PaintingCommandExecutorGPU::draw_triangle_wave(Gfx::IntPoint const&, Gfx::IntPoint const&, Color const&, int, int)
  218. {
  219. // FIXME
  220. return CommandResult::Continue;
  221. }
  222. CommandResult PaintingCommandExecutorGPU::sample_under_corners(BorderRadiusCornerClipper&)
  223. {
  224. // FIXME
  225. return CommandResult::Continue;
  226. }
  227. CommandResult PaintingCommandExecutorGPU::blit_corner_clipping(BorderRadiusCornerClipper&)
  228. {
  229. // FIXME
  230. return CommandResult::Continue;
  231. }
  232. CommandResult PaintingCommandExecutorGPU::paint_borders(DevicePixelRect const& border_rect, CornerRadii const& corner_radii, BordersDataDevicePixels const& borders_data)
  233. {
  234. // FIXME: Add support for corner radiuses
  235. (void)corner_radii;
  236. Gfx::IntRect top_border_rect = {
  237. border_rect.x(),
  238. border_rect.y(),
  239. border_rect.width(),
  240. borders_data.top.width
  241. };
  242. Gfx::IntRect right_border_rect = {
  243. border_rect.x() + (border_rect.width() - borders_data.right.width),
  244. border_rect.y(),
  245. borders_data.right.width,
  246. border_rect.height()
  247. };
  248. Gfx::IntRect bottom_border_rect = {
  249. border_rect.x(),
  250. border_rect.y() + (border_rect.height() - borders_data.bottom.width),
  251. border_rect.width(),
  252. borders_data.bottom.width
  253. };
  254. Gfx::IntRect left_border_rect = {
  255. border_rect.x(),
  256. border_rect.y(),
  257. borders_data.left.width,
  258. border_rect.height()
  259. };
  260. if (borders_data.top.width > 0)
  261. painter().fill_rect(top_border_rect, borders_data.top.color);
  262. if (borders_data.right.width > 0)
  263. painter().fill_rect(right_border_rect, borders_data.right.color);
  264. if (borders_data.bottom.width > 0)
  265. painter().fill_rect(bottom_border_rect, borders_data.bottom.color);
  266. if (borders_data.left.width > 0)
  267. painter().fill_rect(left_border_rect, borders_data.left.color);
  268. return CommandResult::Continue;
  269. }
  270. bool PaintingCommandExecutorGPU::would_be_fully_clipped_by_painter(Gfx::IntRect rect) const
  271. {
  272. auto translation = painter().transform().translation().to_type<int>();
  273. return !painter().clip_rect().intersects(rect.translated(translation));
  274. }
  275. void PaintingCommandExecutorGPU::prepare_glyph_texture(HashMap<Gfx::Font const*, HashTable<u32>> const& unique_glyphs)
  276. {
  277. AccelGfx::GlyphAtlas::the().update(unique_glyphs);
  278. }
  279. void PaintingCommandExecutorGPU::update_immutable_bitmap_texture_cache(HashMap<u32, Gfx::ImmutableBitmap const*>& immutable_bitmaps)
  280. {
  281. painter().update_immutable_bitmap_texture_cache(immutable_bitmaps);
  282. }
  283. }