| // Copyright 2017 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/renderer/rasterizer/lib/external_rasterizer.h" |
| |
| #include <cmath> |
| #include <vector> |
| |
| #include "base/threading/thread_checker.h" |
| #include "cobalt/renderer/backend/egl/graphics_context.h" |
| #include "cobalt/renderer/backend/egl/render_target.h" |
| #include "cobalt/renderer/rasterizer/lib/imported/graphics.h" |
| #include "cobalt/renderer/rasterizer/skia/hardware_rasterizer.h" |
| #include "starboard/shared/gles/gl_call.h" |
| |
| namespace cobalt { |
| namespace renderer { |
| namespace rasterizer { |
| namespace lib { |
| |
| class ExternalRasterizer::Impl { |
| public: |
| Impl(backend::GraphicsContext* graphics_context, int skia_atlas_width, |
| int skia_atlas_height, int skia_cache_size_in_bytes, |
| int scratch_surface_cache_size_in_bytes, int surface_cache_size_in_bytes, |
| bool purge_skia_font_caches_on_destruction); |
| ~Impl(); |
| |
| void Submit(const scoped_refptr<render_tree::Node>& render_tree, |
| const scoped_refptr<backend::RenderTarget>& render_target); |
| |
| render_tree::ResourceProvider* GetResourceProvider(); |
| |
| private: |
| base::ThreadChecker thread_checker_; |
| |
| backend::GraphicsContextEGL* graphics_context_; |
| |
| skia::HardwareRasterizer hardware_rasterizer_; |
| skia::HardwareRasterizer::Options options_; |
| |
| // The main offscreen render target to use when rendering UI or rectangular |
| // video. |
| scoped_refptr<backend::RenderTarget> main_offscreen_render_target_; |
| scoped_ptr<backend::TextureEGL> main_texture_; |
| // TODO: Add in a RenderTarget for the video texture. |
| }; |
| |
| ExternalRasterizer::Impl::Impl(backend::GraphicsContext* graphics_context, |
| int skia_atlas_width, int skia_atlas_height, |
| int skia_cache_size_in_bytes, |
| int scratch_surface_cache_size_in_bytes, |
| int surface_cache_size_in_bytes, |
| bool purge_skia_font_caches_on_destruction) |
| : graphics_context_( |
| base::polymorphic_downcast<backend::GraphicsContextEGL*>( |
| graphics_context)), |
| hardware_rasterizer_( |
| graphics_context, skia_atlas_width, skia_atlas_height, |
| skia_cache_size_in_bytes, scratch_surface_cache_size_in_bytes, |
| surface_cache_size_in_bytes, purge_skia_font_caches_on_destruction) { |
| options_.flags = skia::HardwareRasterizer::kSubmitFlags_Clear; |
| graphics_context_->MakeCurrent(); |
| |
| // TODO: Import the correct size for this and any other textures from the lib |
| // client and re-generate the size as appropriate. |
| main_offscreen_render_target_ = |
| graphics_context_->CreateOffscreenRenderTarget(math::Size(1920, 1080)); |
| main_texture_.reset(new backend::TextureEGL( |
| graphics_context_, |
| make_scoped_refptr(base::polymorphic_downcast<backend::RenderTargetEGL*>( |
| main_offscreen_render_target_.get())))); |
| |
| CbLibOnGraphicsContextCreated(); |
| } |
| |
| ExternalRasterizer::Impl::~Impl() { graphics_context_->MakeCurrent(); } |
| |
| void ExternalRasterizer::Impl::Submit( |
| const scoped_refptr<render_tree::Node>& render_tree, |
| const scoped_refptr<backend::RenderTarget>& render_target) { |
| backend::RenderTargetEGL* render_target_egl = |
| base::polymorphic_downcast<backend::RenderTargetEGL*>( |
| render_target.get()); |
| // When the provided RenderTarget is not a window RenderTarget, then this |
| // implies the rasterized RenderTree should not be shown directly to the user |
| // and thus should not be rasterized into a texture and sent through to the |
| // client implementing CbLibRenderFrame. |
| if (!render_target_egl->IsWindowRenderTarget()) { |
| hardware_rasterizer_.Submit(render_tree, render_target, options_); |
| return; |
| } |
| |
| graphics_context_->MakeCurrentWithSurface(render_target_egl); |
| |
| backend::RenderTargetEGL* main_texture_render_target_egl = |
| base::polymorphic_downcast<backend::RenderTargetEGL*>( |
| main_offscreen_render_target_.get()); |
| hardware_rasterizer_.Submit(render_tree, main_offscreen_render_target_, |
| options_); |
| |
| const intptr_t texture_handle = main_texture_->GetPlatformHandle(); |
| // TODO: Provide mesh data to clients for map-to-mesh playbacks and a |
| // separate video texture handle. |
| // TODO: Allow clients to specify arbitrary subtrees to render into |
| // different textures? |
| CbLibRenderFrame(texture_handle); |
| |
| graphics_context_->SwapBuffers(render_target_egl); |
| } |
| |
| render_tree::ResourceProvider* ExternalRasterizer::Impl::GetResourceProvider() { |
| return hardware_rasterizer_.GetResourceProvider(); |
| } |
| |
| ExternalRasterizer::ExternalRasterizer( |
| backend::GraphicsContext* graphics_context, int skia_atlas_width, |
| int skia_atlas_height, int skia_cache_size_in_bytes, |
| int scratch_surface_cache_size_in_bytes, int surface_cache_size_in_bytes, |
| bool purge_skia_font_caches_on_destruction) |
| : impl_(new Impl( |
| graphics_context, skia_atlas_width, skia_atlas_height, |
| skia_cache_size_in_bytes, scratch_surface_cache_size_in_bytes, |
| surface_cache_size_in_bytes, purge_skia_font_caches_on_destruction)) { |
| } |
| |
| ExternalRasterizer::~ExternalRasterizer() {} |
| |
| void ExternalRasterizer::Submit( |
| const scoped_refptr<render_tree::Node>& render_tree, |
| const scoped_refptr<backend::RenderTarget>& render_target, |
| const Options& options) { |
| impl_->Submit(render_tree, render_target); |
| } |
| |
| render_tree::ResourceProvider* ExternalRasterizer::GetResourceProvider() { |
| return impl_->GetResourceProvider(); |
| } |
| |
| } // namespace lib |
| } // namespace rasterizer |
| } // namespace renderer |
| } // namespace cobalt |