123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- /*
- * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <AK/OwnPtr.h>
- #include <LibGfx/Bitmap.h>
- #include <LibWeb/WebGL/OpenGLContext.h>
- #ifdef HAS_ACCELERATED_GRAPHICS
- # include <LibAccelGfx/Canvas.h>
- # include <LibAccelGfx/Context.h>
- #elif defined(AK_OS_SERENITY)
- # include <LibGL/GLContext.h>
- #endif
- namespace Web::WebGL {
- #ifdef HAS_ACCELERATED_GRAPHICS
- class AccelGfxContext : public OpenGLContext {
- public:
- void activate()
- {
- m_context->activate();
- }
- virtual void present(Gfx::Bitmap& bitmap) override
- {
- VERIFY(bitmap.format() == Gfx::BitmapFormat::BGRA8888);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(0, 0, bitmap.width(), bitmap.height(), GL_BGRA, GL_UNSIGNED_BYTE, bitmap.scanline(0));
- }
- virtual GLenum gl_get_error() override
- {
- activate();
- return glGetError();
- }
- virtual void gl_get_doublev(GLenum pname, GLdouble* params) override
- {
- activate();
- glGetDoublev(pname, params);
- }
- virtual void gl_get_integerv(GLenum pname, GLint* params) override
- {
- activate();
- glGetIntegerv(pname, params);
- }
- virtual void gl_clear(GLbitfield mask) override
- {
- activate();
- glClear(mask);
- }
- virtual void gl_clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) override
- {
- activate();
- glClearColor(red, green, blue, alpha);
- }
- virtual void gl_clear_depth(GLdouble depth) override
- {
- activate();
- glClearDepth(depth);
- }
- virtual void gl_clear_stencil(GLint s) override
- {
- activate();
- glClearStencil(s);
- }
- virtual void gl_active_texture(GLenum texture) override
- {
- activate();
- glActiveTexture(texture);
- }
- virtual void gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
- {
- activate();
- glViewport(x, y, width, height);
- }
- virtual void gl_line_width(GLfloat width) override
- {
- activate();
- glLineWidth(width);
- }
- virtual void gl_polygon_offset(GLfloat factor, GLfloat units) override
- {
- activate();
- glPolygonOffset(factor, units);
- }
- virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) override
- {
- activate();
- glScissor(x, y, width, height);
- }
- virtual void gl_depth_mask(GLboolean mask) override
- {
- activate();
- glDepthMask(mask);
- }
- virtual void gl_depth_func(GLenum func) override
- {
- activate();
- glDepthFunc(func);
- }
- virtual void gl_depth_range(GLdouble z_near, GLdouble z_far) override
- {
- activate();
- glDepthRange(z_near, z_far);
- }
- virtual void gl_cull_face(GLenum mode) override
- {
- activate();
- glCullFace(mode);
- }
- virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) override
- {
- activate();
- glColorMask(red, green, blue, alpha);
- }
- virtual void gl_front_face(GLenum mode) override
- {
- activate();
- glFrontFace(mode);
- }
- virtual void gl_finish() override
- {
- activate();
- glFinish();
- }
- virtual void gl_flush() override
- {
- activate();
- glFlush();
- }
- virtual void gl_stencil_op_separate(GLenum, GLenum, GLenum, GLenum) override
- {
- TODO();
- }
- AccelGfxContext(NonnullOwnPtr<AccelGfx::Context> context, NonnullRefPtr<AccelGfx::Canvas> canvas)
- : m_context(move(context))
- , m_canvas(move(canvas))
- {
- }
- ~AccelGfxContext()
- {
- activate();
- }
- private:
- NonnullOwnPtr<AccelGfx::Context> m_context;
- NonnullRefPtr<AccelGfx::Canvas> m_canvas;
- };
- #endif
- #ifdef AK_OS_SERENITY
- class LibGLContext : public OpenGLContext {
- public:
- virtual void present(Gfx::Bitmap&) override
- {
- m_context->present();
- }
- virtual GLenum gl_get_error() override
- {
- return m_context->gl_get_error();
- }
- virtual void gl_get_doublev(GLenum pname, GLdouble* params) override
- {
- m_context->gl_get_doublev(pname, params);
- }
- virtual void gl_get_integerv(GLenum pname, GLint* params) override
- {
- m_context->gl_get_integerv(pname, params);
- }
- virtual void gl_clear(GLbitfield mask) override
- {
- m_context->gl_clear(mask);
- }
- virtual void gl_clear_color(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) override
- {
- m_context->gl_clear_color(red, green, blue, alpha);
- }
- virtual void gl_clear_depth(GLdouble depth) override
- {
- m_context->gl_clear_depth(depth);
- }
- virtual void gl_clear_stencil(GLint s) override
- {
- m_context->gl_clear_stencil(s);
- }
- virtual void gl_active_texture(GLenum texture) override
- {
- m_context->gl_active_texture(texture);
- }
- virtual void gl_viewport(GLint x, GLint y, GLsizei width, GLsizei height) override
- {
- m_context->gl_viewport(x, y, width, height);
- }
- virtual void gl_line_width(GLfloat width) override
- {
- m_context->gl_line_width(width);
- }
- virtual void gl_polygon_offset(GLfloat factor, GLfloat units) override
- {
- m_context->gl_polygon_offset(factor, units);
- }
- virtual void gl_scissor(GLint x, GLint y, GLsizei width, GLsizei height) override
- {
- m_context->gl_scissor(x, y, width, height);
- }
- virtual void gl_depth_mask(GLboolean flag) override
- {
- m_context->gl_depth_mask(flag);
- }
- virtual void gl_depth_func(GLenum func) override
- {
- m_context->gl_depth_func(func);
- }
- virtual void gl_depth_range(GLdouble z_near, GLdouble z_far) override
- {
- m_context->gl_depth_range(z_near, z_far);
- }
- virtual void gl_cull_face(GLenum mode) override
- {
- m_context->gl_cull_face(mode);
- }
- virtual void gl_color_mask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) override
- {
- m_context->gl_color_mask(red, green, blue, alpha);
- }
- virtual void gl_front_face(GLenum mode) override
- {
- m_context->gl_front_face(mode);
- }
- virtual void gl_finish() override
- {
- m_context->gl_finish();
- }
- virtual void gl_flush() override
- {
- m_context->gl_flush();
- }
- virtual void gl_stencil_op_separate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) override
- {
- m_context->gl_stencil_op_separate(face, sfail, dpfail, dppass);
- }
- LibGLContext(OwnPtr<GL::GLContext> context)
- : m_context(move(context))
- {
- }
- private:
- OwnPtr<GL::GLContext> m_context;
- };
- #endif
- #ifdef HAS_ACCELERATED_GRAPHICS
- static OwnPtr<AccelGfxContext> make_accelgfx_context(Gfx::Bitmap& bitmap)
- {
- auto context = AccelGfx::Context::create();
- if (context.is_error()) {
- dbgln("Failed to create AccelGfx context: {}", context.error().string_literal());
- return {};
- }
- auto canvas = AccelGfx::Canvas::create(bitmap.size());
- canvas->bind();
- return make<AccelGfxContext>(context.release_value(), move(canvas));
- }
- #endif
- #ifdef AK_OS_SERENITY
- static OwnPtr<LibGLContext> make_libgl_context(Gfx::Bitmap& bitmap)
- {
- auto context_or_error = GL::create_context(bitmap);
- return make<LibGLContext>(move(context_or_error.value()));
- }
- #endif
- OwnPtr<OpenGLContext> OpenGLContext::create(Gfx::Bitmap& bitmap)
- {
- #ifdef HAS_ACCELERATED_GRAPHICS
- return make_accelgfx_context(bitmap);
- #elif defined(AK_OS_SERENITY)
- return make_libgl_context(bitmap);
- #endif
- (void)bitmap;
- return {};
- }
- void OpenGLContext::clear_buffer_to_default_values()
- {
- #if defined(HAS_ACCELERATED_GRAPHICS) || defined(AK_OS_SERENITY)
- Array<GLdouble, 4> current_clear_color;
- gl_get_doublev(GL_COLOR_CLEAR_VALUE, current_clear_color.data());
- GLdouble current_clear_depth;
- gl_get_doublev(GL_DEPTH_CLEAR_VALUE, ¤t_clear_depth);
- GLint current_clear_stencil;
- gl_get_integerv(GL_STENCIL_CLEAR_VALUE, ¤t_clear_stencil);
- // The implicit clear value for the color buffer is (0, 0, 0, 0)
- gl_clear_color(0, 0, 0, 0);
- // The implicit clear value for the depth buffer is 1.0.
- gl_clear_depth(1.0);
- // The implicit clear value for the stencil buffer is 0.
- gl_clear_stencil(0);
- gl_clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- // Restore the clear values.
- gl_clear_color(current_clear_color[0], current_clear_color[1], current_clear_color[2], current_clear_color[3]);
- gl_clear_depth(current_clear_depth);
- gl_clear_stencil(current_clear_stencil);
- #endif
- }
- }
|