blob: 56f77ffd243cac1e0c0cdeafdb21e2be0503806a [file] [log] [blame]
// Copyright 2016 The Cobalt Authors. 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 <memory>
#include "cobalt/renderer/rasterizer/blitter/resource_provider.h"
#include "base/bind.h"
#include "cobalt/renderer/rasterizer/blitter/render_tree_blitter_conversions.h"
#include "starboard/blitter.h"
#if SB_API_VERSION < SB_BLITTER_DEPRECATED_VERSION && SB_HAS(BLITTER)
namespace cobalt {
namespace renderer {
namespace rasterizer {
namespace blitter {
using render_tree::AlphaFormat;
using render_tree::Font;
using render_tree::FontProvider;
using render_tree::FontStyle;
using render_tree::FontVector;
using render_tree::GlyphBuffer;
using render_tree::PixelFormat;
using render_tree::Typeface;
ResourceProvider::ResourceProvider(
SbBlitterDevice device,
render_tree::ResourceProvider* skia_resource_provider,
SubmitOffscreenCallback submit_offscreen_callback)
: device_(device),
skia_resource_provider_(skia_resource_provider),
submit_offscreen_callback_(submit_offscreen_callback) {
decode_target_graphics_context_provider_.device = device;
}
bool ResourceProvider::PixelFormatSupported(PixelFormat pixel_format) {
if (pixel_format == render_tree::kPixelFormatUYVY) {
return false;
}
return SbBlitterIsPixelFormatSupportedByPixelData(
device_, RenderTreePixelFormatToBlitter(pixel_format));
}
bool ResourceProvider::AlphaFormatSupported(
render_tree::AlphaFormat alpha_format) {
return alpha_format == render_tree::kAlphaFormatPremultiplied ||
alpha_format == render_tree::kAlphaFormatOpaque;
}
std::unique_ptr<render_tree::ImageData> ResourceProvider::AllocateImageData(
const math::Size& size, PixelFormat pixel_format,
AlphaFormat alpha_format) {
DCHECK(PixelFormatSupported(pixel_format));
DCHECK(AlphaFormatSupported(alpha_format));
std::unique_ptr<render_tree::ImageData> image_data(
new ImageData(device_, size, pixel_format, alpha_format));
if (!image_data->GetMemory()) {
return std::unique_ptr<render_tree::ImageData>();
} else {
return std::move(image_data);
}
}
scoped_refptr<render_tree::Image> ResourceProvider::CreateImage(
std::unique_ptr<render_tree::ImageData> source_data) {
std::unique_ptr<ImageData> blitter_source_data(
base::polymorphic_downcast<ImageData*>(source_data.release()));
return base::WrapRefCounted(
new SinglePlaneImage(std::move(blitter_source_data)));
}
#if SB_HAS(GRAPHICS)
scoped_refptr<render_tree::Image>
ResourceProvider::CreateImageFromSbDecodeTarget(SbDecodeTarget decode_target) {
SbDecodeTargetInfo info;
SbMemorySet(&info, 0, sizeof(info));
CHECK(SbDecodeTargetGetInfo(decode_target, &info));
SbDecodeTargetFormat format = info.format;
if (format == kSbDecodeTargetFormat1PlaneRGBA) {
const SbDecodeTargetInfoPlane& plane =
info.planes[kSbDecodeTargetPlaneRGBA];
DCHECK(SbBlitterIsSurfaceValid(plane.surface));
if (plane.content_region.left != 0 || plane.content_region.top != 0 ||
plane.content_region.right != plane.width ||
plane.content_region.bottom != plane.height) {
NOTREACHED() << "Cobalt has not yet implemented support for Blitter "
"decode target content regions.";
}
return base::WrapRefCounted(new SinglePlaneImage(
plane.surface, info.is_opaque,
base::Bind(&SbDecodeTargetRelease, decode_target)));
}
NOTREACHED()
<< "Only format kSbDecodeTargetFormat1PlaneRGBA is currently supported.";
SbDecodeTargetRelease(decode_target);
return NULL;
}
#endif // SB_HAS(GRAPHICS)
std::unique_ptr<render_tree::RawImageMemory>
ResourceProvider::AllocateRawImageMemory(size_t size_in_bytes,
size_t alignment) {
return skia_resource_provider_->AllocateRawImageMemory(size_in_bytes,
alignment);
}
scoped_refptr<render_tree::Image>
ResourceProvider::CreateMultiPlaneImageFromRawMemory(
std::unique_ptr<render_tree::RawImageMemory> raw_image_memory,
const render_tree::MultiPlaneImageDataDescriptor& descriptor) {
return skia_resource_provider_->CreateMultiPlaneImageFromRawMemory(
std::move(raw_image_memory), descriptor);
}
bool ResourceProvider::HasLocalFontFamily(const char* font_family_name) const {
return skia_resource_provider_->HasLocalFontFamily(font_family_name);
}
scoped_refptr<Typeface> ResourceProvider::GetLocalTypeface(
const char* font_family_name, FontStyle font_style) {
return skia_resource_provider_->GetLocalTypeface(font_family_name,
font_style);
}
scoped_refptr<render_tree::Typeface>
ResourceProvider::GetLocalTypefaceByFaceNameIfAvailable(
const char* font_face_name) {
return skia_resource_provider_->GetLocalTypefaceByFaceNameIfAvailable(
font_face_name);
}
scoped_refptr<Typeface> ResourceProvider::GetCharacterFallbackTypeface(
int32 utf32_character, FontStyle font_style, const std::string& language) {
return skia_resource_provider_->GetCharacterFallbackTypeface(
utf32_character, font_style, language);
}
scoped_refptr<Typeface> ResourceProvider::CreateTypefaceFromRawData(
std::unique_ptr<RawTypefaceDataVector> raw_data,
std::string* error_string) {
return skia_resource_provider_->CreateTypefaceFromRawData(std::move(raw_data),
error_string);
}
float ResourceProvider::GetTextWidth(const base::char16* text_buffer,
size_t text_length,
const std::string& language, bool is_rtl,
FontProvider* font_provider,
FontVector* maybe_used_fonts) {
return skia_resource_provider_->GetTextWidth(text_buffer, text_length,
language, is_rtl, font_provider,
maybe_used_fonts);
}
// Creates a glyph buffer, which is populated with shaped text, and used to
// render that text.
scoped_refptr<GlyphBuffer> ResourceProvider::CreateGlyphBuffer(
const base::char16* text_buffer, size_t text_length,
const std::string& language, bool is_rtl, FontProvider* font_provider) {
return skia_resource_provider_->CreateGlyphBuffer(
text_buffer, text_length, language, is_rtl, font_provider);
}
// Creates a glyph buffer, which is populated with shaped text, and used to
// render that text.
scoped_refptr<GlyphBuffer> ResourceProvider::CreateGlyphBuffer(
const std::string& utf8_string, const scoped_refptr<Font>& font) {
return skia_resource_provider_->CreateGlyphBuffer(utf8_string, font);
}
scoped_refptr<render_tree::Mesh> ResourceProvider::CreateMesh(
std::unique_ptr<std::vector<render_tree::Mesh::Vertex> > vertices,
render_tree::Mesh::DrawMode draw_mode) {
NOTIMPLEMENTED();
return scoped_refptr<render_tree::Mesh>(NULL);
}
scoped_refptr<render_tree::Image> ResourceProvider::DrawOffscreenImage(
const scoped_refptr<render_tree::Node>& root) {
return base::WrapRefCounted(
new SinglePlaneImage(root, submit_offscreen_callback_, device_));
}
} // namespace blitter
} // namespace rasterizer
} // namespace renderer
} // namespace cobalt
#endif // SB_API_VERSION < SB_BLITTER_DEPRECATED_VERSION && SB_HAS(BLITTER)