mirror of
https://github.com/penpot/penpot.git
synced 2025-01-21 22:22:43 -05:00
Merge pull request #5235 from penpot/azazeln28-handle-webgl-context
🎉 Handle WebGL Context
This commit is contained in:
commit
7b196e1ca5
8 changed files with 125 additions and 16 deletions
17
frontend/src/app/main/data/render_wasm.cljs
Normal file
17
frontend/src/app/main/data/render_wasm.cljs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
(ns app.main.data.render-wasm
|
||||||
|
(:require
|
||||||
|
[potok.v2.core :as ptk]))
|
||||||
|
|
||||||
|
(defn context-lost
|
||||||
|
[]
|
||||||
|
(ptk/reify ::context-lost
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :render-state #(assoc % :lost true)))))
|
||||||
|
|
||||||
|
(defn context-restored
|
||||||
|
[]
|
||||||
|
(ptk/reify ::context-restored
|
||||||
|
ptk/UpdateEvent
|
||||||
|
(update [_ state]
|
||||||
|
(update state :render-state #(dissoc % :lost)))))
|
|
@ -116,6 +116,12 @@
|
||||||
|
|
||||||
;; ---- Workspace refs
|
;; ---- Workspace refs
|
||||||
|
|
||||||
|
(def render-state
|
||||||
|
(l/derived :render-state st/state))
|
||||||
|
|
||||||
|
(def render-context-lost?
|
||||||
|
(l/derived :lost render-state))
|
||||||
|
|
||||||
(def workspace-local
|
(def workspace-local
|
||||||
(l/derived :workspace-local st/state))
|
(l/derived :workspace-local st/state))
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@
|
||||||
modifiers (mf/deref refs/workspace-modifiers)
|
modifiers (mf/deref refs/workspace-modifiers)
|
||||||
text-modifiers (mf/deref refs/workspace-text-modifier)
|
text-modifiers (mf/deref refs/workspace-text-modifier)
|
||||||
|
|
||||||
|
render-context-lost? (mf/deref refs/render-context-lost?)
|
||||||
|
|
||||||
objects-modified (mf/with-memo [base-objects text-modifiers modifiers]
|
objects-modified (mf/with-memo [base-objects text-modifiers modifiers]
|
||||||
(apply-modifiers-to-selected selected base-objects text-modifiers modifiers))
|
(apply-modifiers-to-selected selected base-objects text-modifiers modifiers))
|
||||||
|
|
||||||
|
@ -175,6 +177,8 @@
|
||||||
|
|
||||||
mode-inspect? (= options-mode :inspect)
|
mode-inspect? (= options-mode :inspect)
|
||||||
|
|
||||||
|
on-render-restore-context #(.reload js/location)
|
||||||
|
|
||||||
on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?)
|
on-click (actions/on-click hover selected edition drawing-path? drawing-tool space? selrect z?)
|
||||||
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
on-context-menu (actions/on-context-menu hover hover-ids read-only?)
|
||||||
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?)
|
on-double-click (actions/on-double-click hover hover-ids hover-top-frame-id drawing-path? base-objects edition drawing-tool z? read-only?)
|
||||||
|
@ -277,9 +281,9 @@
|
||||||
(p/fmap (fn [ready?]
|
(p/fmap (fn [ready?]
|
||||||
(when ready?
|
(when ready?
|
||||||
(reset! canvas-init? true)
|
(reset! canvas-init? true)
|
||||||
(render.wasm/assign-canvas canvas)))))
|
(render.wasm/setup-canvas canvas)))))
|
||||||
(fn []
|
(fn []
|
||||||
(render.wasm/clear-canvas))))
|
(render.wasm/dispose-canvas canvas))))
|
||||||
|
|
||||||
(mf/with-effect [objects-modified canvas-init?]
|
(mf/with-effect [objects-modified canvas-init?]
|
||||||
(when @canvas-init?
|
(when @canvas-init?
|
||||||
|
@ -635,4 +639,11 @@
|
||||||
{:objects base-objects
|
{:objects base-objects
|
||||||
:zoom zoom
|
:zoom zoom
|
||||||
:vbox vbox
|
:vbox vbox
|
||||||
:bottom-padding (when palete-size (+ palete-size 8))}]]]]]))
|
:bottom-padding (when palete-size (+ palete-size 8))}]]]]
|
||||||
|
|
||||||
|
(when render-context-lost?
|
||||||
|
[:div {:id "context-lost" :class (stl/css :context-lost)}
|
||||||
|
[:h1 "GL Error Screen"]
|
||||||
|
[:button
|
||||||
|
{:on-click on-render-restore-context}
|
||||||
|
"Restore context"]])]))
|
||||||
|
|
|
@ -35,3 +35,13 @@
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.context-lost {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
[app.common.files.helpers :as cfh]
|
[app.common.files.helpers :as cfh]
|
||||||
[app.common.types.shape.impl]
|
[app.common.types.shape.impl]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
|
[app.main.data.render-wasm :as drw]
|
||||||
|
[app.main.store :as st]
|
||||||
|
[app.util.debug :as dbg]
|
||||||
|
[app.util.dom :as dom]
|
||||||
[promesa.core :as p]))
|
[promesa.core :as p]))
|
||||||
|
|
||||||
(def enabled?
|
(def enabled?
|
||||||
|
@ -82,29 +86,67 @@
|
||||||
:stencil true
|
:stencil true
|
||||||
:alpha true})
|
:alpha true})
|
||||||
|
|
||||||
(defn clear-canvas
|
(defn init-skia
|
||||||
[]
|
[canvas]
|
||||||
;; TODO: perform corresponding cleaning
|
(let [init-fn (unchecked-get internal-module "_init")
|
||||||
)
|
state (init-fn (.-width ^js canvas)
|
||||||
|
(.-height ^js canvas))]
|
||||||
|
(set! internal-gpu-state state)))
|
||||||
|
|
||||||
(defn assign-canvas
|
;; NOTE: This function can be called externally
|
||||||
|
;; by the button in the context lost component (shown
|
||||||
|
;; in viewport-wasm) or called internally by
|
||||||
|
;; on-webgl-context
|
||||||
|
(defn restore-canvas
|
||||||
|
[canvas]
|
||||||
|
(st/emit! (drw/context-restored))
|
||||||
|
;; We need to reinitialize skia when the
|
||||||
|
;; context is restored.
|
||||||
|
(init-skia canvas))
|
||||||
|
|
||||||
|
;; Handles both events: webglcontextlost and
|
||||||
|
;; webglcontextrestored
|
||||||
|
(defn on-webgl-context
|
||||||
|
[event]
|
||||||
|
(dom/prevent-default event)
|
||||||
|
(if (= (.-type event) "webglcontextlost")
|
||||||
|
(st/emit! (drw/context-lost))
|
||||||
|
(restore-canvas (dom/get-target event))))
|
||||||
|
|
||||||
|
(defn dispose-canvas
|
||||||
|
[canvas]
|
||||||
|
;; TODO: perform corresponding cleaning
|
||||||
|
(.removeEventListener canvas "webglcontextlost" on-webgl-context)
|
||||||
|
(.removeEventListener canvas "webglcontextrestored" on-webgl-context))
|
||||||
|
|
||||||
|
(defn init-debug-webgl-context-state
|
||||||
|
[context]
|
||||||
|
(let [context-extension (.getExtension ^js context "WEBGL_lose_context")
|
||||||
|
info-extension (.getExtension ^js context "WEBGL_debug_renderer_info")]
|
||||||
|
(set! (.-penpotGL js/window) #js {:context context-extension
|
||||||
|
:renderer info-extension})
|
||||||
|
(js/console.log "WEBGL_lose_context" context-extension)
|
||||||
|
(js/console.log "WEBGL_debug_renderer_info" info-extension)))
|
||||||
|
|
||||||
|
(defn setup-canvas
|
||||||
[canvas]
|
[canvas]
|
||||||
(let [gl (unchecked-get internal-module "GL")
|
(let [gl (unchecked-get internal-module "GL")
|
||||||
init-fn (unchecked-get internal-module "_init")
|
|
||||||
|
|
||||||
context (.getContext ^js canvas "webgl2" canvas-options)
|
context (.getContext ^js canvas "webgl2" canvas-options)
|
||||||
|
|
||||||
;; Register the context with emscripten
|
;; Register the context with emscripten
|
||||||
handle (.registerContext ^js gl context #js {"majorVersion" 2})
|
handle (.registerContext ^js gl context #js {"majorVersion" 2})
|
||||||
_ (.makeContextCurrent ^js gl handle)
|
_ (.makeContextCurrent ^js gl handle)]
|
||||||
|
|
||||||
;; Initialize Skia
|
(when (dbg/enabled? :gl-context)
|
||||||
state (init-fn (.-width ^js canvas)
|
(init-debug-webgl-context-state context))
|
||||||
(.-height ^js canvas))]
|
|
||||||
|
(.addEventListener canvas "webglcontextlost" on-webgl-context)
|
||||||
|
(.addEventListener canvas "webglcontextrestored" on-webgl-context)
|
||||||
|
|
||||||
(set! (.-width canvas) (.-clientWidth ^js canvas))
|
(set! (.-width canvas) (.-clientWidth ^js canvas))
|
||||||
(set! (.-height canvas) (.-clientHeight ^js canvas))
|
(set! (.-height canvas) (.-clientHeight ^js canvas))
|
||||||
(set! internal-gpu-state state)))
|
|
||||||
|
(init-skia canvas)))
|
||||||
|
|
||||||
(defonce module
|
(defonce module
|
||||||
(->> (js/dynamicImport "/js/render_wasm.js")
|
(->> (js/dynamicImport "/js/render_wasm.js")
|
||||||
|
|
|
@ -89,7 +89,10 @@
|
||||||
:display-touched
|
:display-touched
|
||||||
|
|
||||||
;; Show some visual indicators for bool shape
|
;; Show some visual indicators for bool shape
|
||||||
:bool-shapes})
|
:bool-shapes
|
||||||
|
|
||||||
|
;; Show some information about the WebGL context.
|
||||||
|
:gl-context})
|
||||||
|
|
||||||
(defn enable!
|
(defn enable!
|
||||||
[option]
|
[option]
|
||||||
|
|
18
render-wasm/Cargo.lock
generated
18
render-wasm/Cargo.lock
generated
|
@ -96,6 +96,22 @@ version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "emscripten-functions"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "62c026cc030b24957ca45d9555f9fa241d6b3a01d725cd98a25924de249b840a"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"emscripten-functions-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "emscripten-functions-sys"
|
||||||
|
version = "4.1.67"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "65715a5f07b03636d7cd5508a45d1b62486840cb7d91a66564a73f1d7aa70b79"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -370,6 +386,8 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
name = "render"
|
name = "render"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"emscripten-functions",
|
||||||
|
"emscripten-functions-sys",
|
||||||
"gl",
|
"gl",
|
||||||
"skia-safe",
|
"skia-safe",
|
||||||
]
|
]
|
||||||
|
|
|
@ -11,6 +11,8 @@ name = "render_wasm"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
emscripten-functions = "0.2.3"
|
||||||
|
emscripten-functions-sys = "4.1.67"
|
||||||
gl = "0.14.0"
|
gl = "0.14.0"
|
||||||
skia-safe = { version = "0.78.2", features = ["gl"] }
|
skia-safe = { version = "0.78.2", features = ["gl"] }
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue