blob: 8912c232c0fd41698fb42be165535f4a00844f6d [file] [log] [blame]
// 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_