| // Copyright 2016 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. |
| |
| #ifndef COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_ |
| #define COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_ |
| |
| #include <string> |
| |
| #include "base/callback.h" |
| #include "base/optional.h" |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| #include "cobalt/base/console_commands.h" |
| #endif |
| #include "cobalt/renderer/rasterizer/blitter/render_state.h" |
| #include "cobalt/renderer/rasterizer/common/offscreen_render_coordinate_mapping.h" |
| #include "cobalt/renderer/rasterizer/common/surface_cache.h" |
| #include "starboard/blitter.h" |
| |
| #if SB_HAS(BLITTER) |
| |
| namespace cobalt { |
| namespace renderer { |
| namespace rasterizer { |
| namespace blitter { |
| |
| // Implements blitter-specific cache recording and playback surface management |
| // in order to provide blitter-support for the render tree surface caching |
| // system. |
| class SurfaceCacheDelegate : public common::SurfaceCache::Delegate { |
| private: |
| class CachedSurface : public common::SurfaceCache::CachedSurface { |
| public: |
| CachedSurface(SbBlitterSurface surface, |
| const math::Vector2dF& output_post_scale, |
| const math::Vector2dF& output_pre_translate, |
| const math::Rect& output_bounds) |
| : surface_(surface), |
| output_post_scale_(output_post_scale), |
| output_pre_translate_(output_pre_translate), |
| output_bounds_(output_bounds) {} |
| ~CachedSurface() OVERRIDE { SbBlitterDestroySurface(surface_); } |
| |
| SbBlitterSurface surface() const { return surface_; } |
| const math::Vector2dF& output_post_scale() const { |
| return output_post_scale_; |
| } |
| const math::Vector2dF& output_pre_translate() const { |
| return output_pre_translate_; |
| } |
| const math::Rect& output_bounds() const { return output_bounds_; } |
| |
| private: |
| // The actual surface representing the cached render tree. |
| SbBlitterSurface surface_; |
| |
| // When applying |surface_| to another render target, the current |
| // transformation should be post-multiplied by |output_post_scale_|, and |
| // pre-multiplied by |output_pre_translate_|. |
| math::Vector2dF output_post_scale_; |
| math::Vector2dF output_pre_translate_; |
| // The rectangle coordinates into which |surface_| should be rendered. |
| math::Rect output_bounds_; |
| }; |
| |
| public: |
| typedef base::Callback<RenderState*(const RenderState&)> |
| SetRenderStateFunction; |
| |
| // Creating a ScopedContext object declares a render tree visitor context, |
| // and so there should be one ScopedContext per render tree visitor. Since |
| // it is typical to recursively create sub render tree visitors, this class |
| // is designed to be instantiated multiple times on the same |
| // SurfaceCacheDelegate object. |
| class ScopedContext { |
| public: |
| ScopedContext(SurfaceCacheDelegate* delegate, RenderState* render_state, |
| const SetRenderStateFunction& set_render_state_function) |
| : delegate_(delegate), |
| old_render_state_(delegate_->render_state_), |
| old_set_render_state_function_( |
| delegate_->set_render_state_function_) { |
| // Setup our new render target to the provided one. Remember a new method |
| // to set the render target for the current rendering context in case we |
| // need to start recording on a offscreen surface. |
| delegate_->render_state_ = render_state; |
| delegate_->set_render_state_function_ = set_render_state_function; |
| } |
| ~ScopedContext() { |
| // Restore the render target to the old setting. |
| delegate_->set_render_state_function_ = old_set_render_state_function_; |
| delegate_->render_state_ = old_render_state_; |
| } |
| |
| private: |
| SurfaceCacheDelegate* delegate_; |
| RenderState* old_render_state_; |
| SetRenderStateFunction old_set_render_state_function_; |
| }; |
| |
| SurfaceCacheDelegate(SbBlitterDevice device, SbBlitterContext context); |
| |
| void ApplySurface(common::SurfaceCache::CachedSurface* surface) OVERRIDE; |
| void StartRecording(const math::RectF& local_bounds) OVERRIDE; |
| common::SurfaceCache::CachedSurface* EndRecording() OVERRIDE; |
| void ReleaseSurface(common::SurfaceCache::CachedSurface* surface) OVERRIDE; |
| math::Size GetRenderSize(const math::SizeF& local_size) OVERRIDE; |
| math::Size MaximumSurfaceSize() OVERRIDE; |
| |
| private: |
| // Defines a set of data that is relevant only while recording. |
| struct RecordingData { |
| RecordingData(const RenderState& original_render_state, |
| const common::OffscreenRenderCoordinateMapping& coord_mapping, |
| SbBlitterSurface surface) |
| : original_render_state(original_render_state), |
| coord_mapping(coord_mapping), |
| surface(surface) {} |
| |
| // The original render state that the recorded draw calls would have |
| // otherwise targeted if we were not recording. |
| RenderState original_render_state; |
| |
| // Information about how to map the offscreen cached surface to the main |
| // render target. |
| common::OffscreenRenderCoordinateMapping coord_mapping; |
| |
| // The offscreen cached surface that we are recording to. |
| SbBlitterSurface surface; |
| }; |
| |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| void OnToggleCacheHighlights(const std::string& message); |
| #endif |
| |
| SbBlitterDevice device_; |
| SbBlitterContext context_; |
| |
| // A function that can be used to change the current render state in order to |
| // affect subsequent blitter render tree node visitor rasterization commands |
| // to an offscreen cached surface with a custom transform and clip stack. |
| SetRenderStateFunction set_render_state_function_; |
| |
| // The current render state that is being used, whether it is cached surface |
| // recording state (e.g. render to an offscreen surface) or the normal |
| // render state currently in use by a render tree node visitor client. |
| RenderState* render_state_; |
| |
| // If we are currently recording, this will contain all of the data relevant |
| // to that recording. |
| base::optional<RecordingData> recording_data_; |
| |
| #if defined(ENABLE_DEBUG_CONSOLE) |
| // Debug command to toggle cache highlights to help visualize which nodes |
| // are being cached. |
| bool toggle_cache_highlights_; |
| base::ConsoleCommandManager::CommandHandler |
| toggle_cache_highlights_command_handler_; |
| #endif |
| }; |
| |
| } // namespace blitter |
| } // namespace rasterizer |
| } // namespace renderer |
| } // namespace cobalt |
| |
| #endif // #if SB_HAS(BLITTER) |
| |
| #endif // COBALT_RENDERER_RASTERIZER_BLITTER_SURFACE_CACHE_DELEGATE_H_ |