Chromeカーネル解析--描画エンジン基礎編:描画コンテキスト(RenderingContext,GraphicsContext)


転載は出典を明記してください.http://blog.csdn.net/yunchao_he/article/details/41698169
複数のグラフィックコンテキスト(GraphicsContext、3 D Context、GL Contextとも呼ばれる)
OpenGL/D 3 D描画、またはGDI、GTK/CAリオ、QT、X 11、Skiaなどの描画に関するライブラリを使用する場合、グラフィックコンテキスト(GraphicsContext)という概念が知られている.プロセスコンテキストと似ていますが、現在申請されているBuffer、Texture、FBOなどのオブジェクトや、Textureのtile mode(repeat,mirror)、変換マトリクス、投影マトリクス、光照射情報、線幅、線の色、剪断領域の大きさ、alpha混合モード、パラメータなどの図形描画に関する情報を保存します.など多くの関連属性があります.Chromiumでは、マルチプロセスフレームワークとWebコンテンツの複雑さのため、次のような複数のGraphicsContextが含まれている可能性があります.
まず、Webページの特殊な要素やコンポーネントはChromiumに独自のGraphicsContextがあります.これらの特殊な要素はWebGL、Canvas 2 D、Video、Pepper 3 Dなどです.ページに特殊な要素が表示されるたびに、Chromiumは独立したGraphicsContextを作成します.また、他のすべての要素を含むBase Layer(Root Layerとも呼ばれる)にも独自のGraphicsContextがあります.これらはoff-screenのFBO、例えばPixelBuffeやTextureに描かれています.
次に、RenderCompositorは上記の各Layerを合成し、合成中にも独自のGraphicsContextを作成し、off-screenに描画されたFBOでもある.
最終的には、BrowserCompositorがWebコンテンツとUIを合成し、GrapicsContextも作成します.この合成の結果は画面に描画されます.on-screen Framebufferに対応しています.最も一般的なデュアルbufferシステムでは、back bufferに描画され、swap bufferで画面に表示されます.
仮想コンテキスト:Virtual Context
GPUハードウェアで複数のGraphicsContexts(またはサポートされているがパフォーマンスが悪い)がサポートされていないデバイスの場合、Chromiumは仮想コンテキストを作成します.各仮想コンテキストは、バインドされたFBO、texture、bufferなど、独自の描画ステータスとプロパティを維持します.複数の仮想コンテキストは、実際のGraphicsContextに対応します.仮想コンテキストを切り替える場合は、bufferを再バインドし、ペイントステータスを復元する必要があります.
したがって、仮想コンテキストの切り替えは論理的な切り替えにすぎず、GraphicsContextは実際に切り替えられていない.この方法は、複数のグラフィックコンテキストをサポートしないデバイス上で、仮想コンテキストによって複数のグラフィックコンテキストをシミュレートすることができる.
RenderingContext 
実際、ChromiumではGraphicsContextを管理するためにCommand Bufferの作成時にGraphicsContextとVirtual Contextだけでなく、TransferBufferManager、Command BufferService、GLES 2 DecoderImpl、GpuScheduler、GLES 2 Implementation、GLES 2 CommdHelper、TransferBufferなど、描画に関連する他の重要なクラスも作成されています.これらのクラスはGraphicsContext,Virtual ContextとともにChromiumの描画コンテキスト(RenderingContext)を構成している.特にGLES 2 DecoderImplは、command bufferクライアントからのGpu要求を解析し、GL操作を本格的に開始する責任を負います.その初期化関数gpu::gles 2::GLES 2 DecoderImpl::Initializeでは、FBOやFBOにattachを必要とするcolor buffer(TextureまたはRenderBuffer)、depth buffer、stencil bufferなど、多くの重要なインフラストラクチャが作成されます.
これらのクラスはCommand Bufferと密接に関連しており、次のセクションで詳しく説明します.Chromiumでは、複数のGraphicsContextをサポートするために、コマンドバッファメカニズムが導入されていることを理解する必要があります.複数のグラフィックコンテキストを切り替え、同期する必要があります.したがって、GraphicsContext自体に加えて、ChromiumのRenderingContextには多くのインフラストラクチャが含まれており、このメカニズムを実現しています.
(注意:GraphicContextとRenderingContextはいずれも描画コンテキストに翻訳可能であり、ChromiumではRenderingContextにGraphicsContextが含まれ、VirtualContext,GpuScheduler,GLES 2 Decoder,GLES 2 Implementationなども含まれる.混同を避けるためにGraphicsContextをグラフィックコンテキストに翻訳するほか、RenderingContextを描画コンテキストに翻訳するほか、なるべく英語の原文で
Chromiumの具体的な実装:
1.RenderingContext,GraphicsContext,VirtualContextの作成
WebGLの場合、JavaScriptがgetContext(「webgl」)を呼び出すと、GraphicsContextとVirtualContextが作成されます.具体的には、Renderプロセスのメインスレッドで、V 8が
getContext("webgl");  //   getContext("experimental-webgl");

を選択すると、JS bindingからBlinkに移動し、対応するAPI:blink::HTML CanvasElement::getContextを呼び出します.WebGLRenderingContextを作成します.Chromiumのcontentモジュールを呼び出し、GraphicsContextとVirtual Contextを含むRenderingContextを作成します.主な呼び出しシーケンスは次のとおりです.
blink::HTMLCanvasElement::getContext 
blink::WebGLRenderingContext::create 
content::RendererBlinkPlatformImpl::createOffscreenGraphicContext3D 
content::WebGraphicsContext3DCommandBufferImpl::InitializeOnCurrentThread 
content::WebGrapicsContext3DCommandBufferImpl::CreateContext 
content::CommandBufferProxyImpl::Initialize

もちろん、実際にGraphicsContextを作成するには、eglCreateContextなどのGL操作を開始する必要があります.ChromiumにはGL操作はBrowserプロセスのGpuスレッドが担当するという簡単な原則があります.同様に、上記のコード自体はRenderingContextを作成するプロセスを完了しておらず、Browserプロセスに作成要求(GpuCommandBufferMsg_Initializeメッセージを送信)を送信し、Browserプロセスがこの要求を受信すると、
content::GpuCommandBufferStub::OnInitialize
はcommand bufferの初期化を担当し、GraphicsContextはcommand bufferの初期化中に作成されます.具体的には、gfx::GLSurface::CreateOffscreenGLSurfaceまたはgfx::GLSurface::CreateViewSurfaceを呼び出してGLSurfaceを作成し、gfx::GLContext::CreateGLContextを呼び出してグラフィックコンテキストを作成する.仮想コンテキストはgpu::GLContextVirtual::GLContextVirtualを呼び出して作成します.その他のRenderingContextに関連するクラスも、Command Bufferの初期化時に作成されます.例えば、GpuScheduler、GLES 2 Implementation、GLES 2 DecoderImplなどです.特に重要なのはgpu::gles 2::GLES 2 DecoderImpl::Initializeでoff-screen GraphicsContextのFBO、FBOに必要なtextureとrender bufferです.Browserプロセスのメインスレッドにあります.
もちろん、GLSurfaceとGLContextはプラットフォームに関連しており、egl、CGLなどの特定のライブラリを呼び出して実装されます.Gpuスレッドにあります.Chromium on Androidを例にとると、GraphicsContextは/src/ui/gl_context_android.ccのファクトリ関数CLContext::CreateGLContext、最終的にGLContextEGL::eglCreateContextを呼び出して作成します(/src/ui/gl/gl_context_egl.cc).仮想コンテキストの作成は、プラットフォームとは無関係であり、Browserプロセスのメインスレッドで完了します.
プロセス全体は次のとおりです.
Chrome内核解析 -- 绘制引擎基础篇:绘图上下文(RenderingContext, GraphicsContext)_第1张图片
2.コンテキストの切り替え
コンテキスト切り替えは,実際にはターゲットContextを現在のContextとする.Chromiumではgpu::GLContext::MakeCurrentを呼び出します.ターゲットContextがプラットフォーム関連のリアル3 D Context(具体的にはGLContextEGL,GLContextWGL,GLContextGLXなどが実装されている)であっても、プラットフォーム関連のVirtual Contextであっても、GLContextのサブクラスである.gpu::GLContext::MakeCurrentを呼び出すことで、特定のクラスに動的にバインドできます.具体的な分析は以下の通りである.
切り替えられたターゲットContextが実際のGraphicsContextである場合、GLContextEGL::MakeCurrentなどのプラットフォーム関連のMakeCurrent関数が呼び出されます.最終的には、eglMakeCurrentなどのプラットフォーム関連GLアクションが呼び出されます.実際の3 D Contextの切り替え操作は時間がかかります.具体的なコードは/src/ui/glディレクトリの下にある関連ファイルにあります.
VirtualContextの場合、GLContextVirtualが呼び出されます.現在のリアル3 D ContextとターゲットContextが同じかどうかを確認します.同じ場合は、実際のGraphicsContextを切り替える必要はありません.複数のGraphicsContextがサポートされていないデバイスでは、最初の呼び出しMakeCurrentが実際のGraphicsContextに切り替わる以外は、実際のGraphicsContextを切り替える必要はありません.仮想コンテキストを切り替える関数は/src/ui/gl/gl_です.gl_api_implementation.ccのgfx::VirtualGLApi::MakeCurrent.GLContextVirtual::MakeCurrentからこの関数への呼び出しシーケンスは次のとおりです.
gpu::GLContextVirtual::MakeCurrent
gfx::GLContext::MakeVirtuallyCurrent
gfx::VirtualGLApi::MakeCurrent

前述したように、VirtualContextを切り替えるには、主にbufferを再バインドし、状態パラメータを明示的に設定して関連するペイント状態を復元します.通常、仮想コンテキストの切り替えは軽量レベルです.