C-WebGL: 結局、GLESコンテキストは共有できるのか問題
AppleのOpenGL ESには EAGLSharegroup
があり、これを使用した並列化がテクニックとして公式ドキュメントに紹介されている。
同じことが他所のプラットフォームでできるのか問題がある。
(いわゆる "モダン" APIでは、当然リソースのアップロードをマルチスレッドで処理できるためこれは問題にならない)
share_context
EGLの
eglCreateContext
には引数 share_context
があり、既存のコンテキストと一部のオブジェクトを共有できるとされている。何が共有されるかはAPIごとに規定されることになっている。
GLES3.0のAppendix Dには以下の記述がある:
Objects that can be shared between contexts include buffer objects, program and shader objects, renderbuffer objects, sync objects, sampler objects, and texture objects (except for the texture objects named zero).
Framebuffer, query, transform feedback, and vertex array objects are not
shared.
特に、FramebufferとVAOは共有できない。
また重要な制約として、EGL 1.5 の 3.7 Rendering Contexts に
The minimum number of current contexts that must be supported by an EGL implementation is one for each supported client API
とあり、 2つ以上のコンテキストを同時に別々のスレッドのcurrent contextにできることは保証されていない 。このため、Appleの実装のように、リソースのアップロードと使用を別々のコンテキストで行うことで並列化することがサポートされているとは限らない。
Android
ARMのOpenGL ES SDKでは、Apple同様にテクスチャのアップロードと描画を別々のスレッドで行うサンプルを用意している:
ただしGoogleのbugtrackerには、このような方法で共有されたコンテキストのクラッシュレポートがある:
なのでこれに依存するのは安全でないかもしれない。このレポート自体は、今年不再現で閉じられている。
ANGLE
少くとも2016年には、複数コンテキストの平行利用はサポート外とされている:
ただし、現在では少くともVulkanはshared contextをサポートしているらしい:
Because we hold the necessary locks at the entry point. See GL_GenTextures in entry_points_gles_2_0_autogen.cpp for example, which includes SCOPED_SHARE_CONTEXT_LOCK(context); before the texture manager is accessed.