Commit e19973e8 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Implement OOP-R on RasterDecoder.

This CL makes --enable-oop-rasterization --enable-raster-decoder work on
desktop linux builds of chromium.

Changes:

- Update raster_cmd_buffer_functions.txt with changes in
  gles2_cmd_buffer_functions.txt and regenerate autogen files.

- Copy code from RasterImplementationGLES into RasterImplementation.

- Copy code from GLES2DecoderImpl into RasterDecoderImpl

Bug: 789238
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ia7b50acc843ecd641a8a74927d94303138849e86
Reviewed-on: https://chromium-review.googlesource.com/1011203Reviewed-by: default avatarkylechar <kylechar@chromium.org>
Commit-Queue: Jonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551797}
parent 7100ca5a
......@@ -9,6 +9,7 @@
#include <memory>
#include <utility>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
......@@ -28,6 +29,7 @@ class SkCanvas;
namespace gpu {
namespace raster {
class RasterImplementation;
class RasterImplementationGLES;
} // namespace raster
} // namespace gpu
......@@ -192,6 +194,7 @@ class CC_PAINT_EXPORT DisplayItemList
private:
FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, AsValueWithNoOps);
FRIEND_TEST_ALL_PREFIXES(DisplayItemListTest, AsValueWithOps);
friend gpu::raster::RasterImplementation;
friend gpu::raster::RasterImplementationGLES;
~DisplayItemList();
......
......@@ -164,12 +164,13 @@ void BeginRasterCHROMIUM(GLuint texture_id,
GLuint sk_color,
GLuint msaa_sample_count,
GLboolean can_use_lcd_text,
GLint color_type) {
GLint color_type,
GLuint color_space_transfer_cache_id) {
raster::cmds::BeginRasterCHROMIUM* c =
GetCmdSpace<raster::cmds::BeginRasterCHROMIUM>();
if (c) {
c->Init(texture_id, sk_color, msaa_sample_count, can_use_lcd_text,
color_type);
color_type, color_space_transfer_cache_id);
}
}
......
......@@ -10,9 +10,13 @@
#include <GLES3/gl3.h>
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
#include <limits>
#include <set>
#include <sstream>
#include <string>
#include "base/atomic_sequence_num.h"
#include "base/bits.h"
#include "base/compiler_specific.h"
......@@ -23,6 +27,12 @@
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/color_space_transfer_cache_entry.h"
#include "cc/paint/decode_stashing_image_provider.h"
#include "cc/paint/display_item_list.h"
#include "cc/paint/paint_op_buffer_serializer.h"
#include "cc/paint/transfer_cache_entry.h"
#include "cc/paint/transfer_cache_serialize_helper.h"
#include "gpu/command_buffer/client/gpu_control.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/raster_cmd_helper.h"
......@@ -73,6 +83,117 @@ using gpu::gles2::GLES2Util;
namespace gpu {
namespace raster {
namespace {
// Helper to copy data to the GPU service over the transfer cache.
class TransferCacheSerializeHelperImpl
: public cc::TransferCacheSerializeHelper {
public:
explicit TransferCacheSerializeHelperImpl(ContextSupport* support)
: support_(support) {}
~TransferCacheSerializeHelperImpl() final = default;
private:
bool LockEntryInternal(const EntryKey& key) final {
return support_->ThreadsafeLockTransferCacheEntry(
static_cast<uint32_t>(key.first), key.second);
}
void CreateEntryInternal(const cc::ClientTransferCacheEntry& entry) final {
size_t size = entry.SerializedSize();
void* data = support_->MapTransferCacheEntry(size);
// TODO(piman): handle error (failed to allocate/map shm)
DCHECK(data);
bool succeeded = entry.Serialize(
base::make_span(reinterpret_cast<uint8_t*>(data), size));
DCHECK(succeeded);
support_->UnmapAndCreateTransferCacheEntry(entry.UnsafeType(), entry.Id());
}
void FlushEntriesInternal(std::set<EntryKey> entries) final {
std::vector<std::pair<uint32_t, uint32_t>> transformed;
transformed.reserve(entries.size());
for (const auto& e : entries)
transformed.emplace_back(static_cast<uint32_t>(e.first), e.second);
support_->UnlockTransferCacheEntries(transformed);
}
ContextSupport* const support_;
DISALLOW_COPY_AND_ASSIGN(TransferCacheSerializeHelperImpl);
};
// Helper to copy PaintOps to the GPU service over the transfer buffer.
class PaintOpSerializer {
public:
PaintOpSerializer(size_t initial_size,
RasterImplementation* ri,
cc::DecodeStashingImageProvider* stashing_image_provider,
cc::TransferCacheSerializeHelper* transfer_cache_helper)
: ri_(ri),
buffer_(static_cast<char*>(ri_->MapRasterCHROMIUM(initial_size))),
stashing_image_provider_(stashing_image_provider),
transfer_cache_helper_(transfer_cache_helper),
free_bytes_(buffer_ ? initial_size : 0) {}
~PaintOpSerializer() {
// Need to call SendSerializedData;
DCHECK(!written_bytes_);
}
size_t Serialize(const cc::PaintOp* op,
const cc::PaintOp::SerializeOptions& options) {
if (!valid())
return 0;
size_t size = op->Serialize(buffer_ + written_bytes_, free_bytes_, options);
if (!size) {
SendSerializedData();
buffer_ = static_cast<char*>(ri_->MapRasterCHROMIUM(kBlockAlloc));
if (!buffer_) {
free_bytes_ = 0;
return 0;
}
free_bytes_ = kBlockAlloc;
size = op->Serialize(buffer_ + written_bytes_, free_bytes_, options);
}
DCHECK_LE(size, free_bytes_);
written_bytes_ += size;
free_bytes_ -= size;
return size;
}
void SendSerializedData() {
if (!valid())
return;
ri_->UnmapRasterCHROMIUM(written_bytes_);
// Now that we've issued the RasterCHROMIUM referencing the stashed
// images, Reset the |stashing_image_provider_|, causing us to issue
// unlock commands for these images.
stashing_image_provider_->Reset();
transfer_cache_helper_->FlushEntries();
written_bytes_ = 0;
}
bool valid() const { return !!buffer_; }
private:
static constexpr GLsizeiptr kBlockAlloc = 512 * 1024;
RasterImplementation* const ri_;
char* buffer_;
cc::DecodeStashingImageProvider* const stashing_image_provider_;
cc::TransferCacheSerializeHelper* const transfer_cache_helper_;
size_t written_bytes_ = 0;
size_t free_bytes_ = 0;
DISALLOW_COPY_AND_ASSIGN(PaintOpSerializer);
};
} // namespace
RasterImplementation::SingleThreadChecker::SingleThreadChecker(
RasterImplementation* raster_implementation)
: raster_implementation_(raster_implementation) {
......@@ -948,10 +1069,26 @@ void RasterImplementation::BeginRasterCHROMIUM(
GLuint sk_color,
GLuint msaa_sample_count,
GLboolean can_use_lcd_text,
GLint pixel_config,
GLint color_type,
const cc::RasterColorSpace& raster_color_space) {
NOTIMPLEMENTED();
TransferCacheSerializeHelperImpl transfer_cache_serialize_helper(this);
if (!transfer_cache_serialize_helper.LockEntry(
cc::TransferCacheEntryType::kColorSpace,
raster_color_space.color_space_id)) {
transfer_cache_serialize_helper.CreateEntry(
cc::ClientColorSpaceTransferCacheEntry(raster_color_space));
}
transfer_cache_serialize_helper.AssertLocked(
cc::TransferCacheEntryType::kColorSpace,
raster_color_space.color_space_id);
helper_->BeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count,
can_use_lcd_text, color_type,
raster_color_space.color_space_id);
transfer_cache_serialize_helper.FlushEntries();
background_color_ = sk_color;
}
void RasterImplementation::RasterCHROMIUM(const cc::DisplayItemList* list,
cc::ImageProvider* provider,
const gfx::Size& content_size,
......@@ -960,8 +1097,48 @@ void RasterImplementation::RasterCHROMIUM(const cc::DisplayItemList* list,
const gfx::Vector2dF& post_translate,
GLfloat post_scale,
bool requires_clear) {
NOTIMPLEMENTED();
if (std::abs(post_scale) < std::numeric_limits<float>::epsilon())
return;
gfx::Rect query_rect =
gfx::ScaleToEnclosingRect(playback_rect, 1.f / post_scale);
std::vector<size_t> offsets = list->rtree_.Search(query_rect);
if (offsets.empty())
return;
// TODO(enne): Tune these numbers
// TODO(enne): Convert these types here and in transfer buffer to be size_t.
static constexpr unsigned int kMinAlloc = 16 * 1024;
unsigned int free_size = std::max(GetTransferBufferFreeSize(), kMinAlloc);
// This section duplicates RasterSource::PlaybackToCanvas setup preamble.
cc::PaintOpBufferSerializer::Preamble preamble;
preamble.content_size = content_size;
preamble.full_raster_rect = full_raster_rect;
preamble.playback_rect = playback_rect;
preamble.post_translation = post_translate;
preamble.post_scale = gfx::SizeF(post_scale, post_scale);
preamble.requires_clear = requires_clear;
preamble.background_color = background_color_;
// Wrap the provided provider in a stashing provider so that we can delay
// unrefing images until we have serialized dependent commands.
cc::DecodeStashingImageProvider stashing_image_provider(provider);
// TODO(enne): Don't access private members of DisplayItemList.
TransferCacheSerializeHelperImpl transfer_cache_serialize_helper(this);
PaintOpSerializer op_serializer(free_size, this, &stashing_image_provider,
&transfer_cache_serialize_helper);
cc::PaintOpBufferSerializer::SerializeCallback serialize_cb =
base::BindRepeating(&PaintOpSerializer::Serialize,
base::Unretained(&op_serializer));
cc::PaintOpBufferSerializer serializer(serialize_cb, &stashing_image_provider,
&transfer_cache_serialize_helper);
serializer.Serialize(&list->paint_op_buffer_, &offsets, preamble);
// TODO(piman): raise error if !serializer.valid()?
op_serializer.SendSerializedData();
}
void RasterImplementation::BeginGpuRaster() {
NOTIMPLEMENTED();
}
......
......@@ -29,6 +29,7 @@
#include "gpu/command_buffer/common/id_allocator.h"
#include "gpu/command_buffer/common/raster_cmd_format.h"
#include "gpu/raster_export.h"
#include "third_party/skia/include/core/SkColor.h"
namespace gpu {
......@@ -104,7 +105,7 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface,
GLuint sk_color,
GLuint msaa_sample_count,
GLboolean can_use_lcd_text,
GLint pixel_config,
GLint color_type,
const cc::RasterColorSpace& raster_color_space) override;
void RasterCHROMIUM(const cc::DisplayItemList* list,
cc::ImageProvider* provider,
......@@ -144,6 +145,9 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface,
GLenum pname,
GLuint64* params);
void* MapRasterCHROMIUM(GLsizeiptr size);
void UnmapRasterCHROMIUM(GLsizeiptr written_size);
private:
friend class RasterImplementationTest;
......@@ -226,9 +230,6 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface,
void FailGLError(GLenum /* error */) {}
#endif
void* MapRasterCHROMIUM(GLsizeiptr size);
void UnmapRasterCHROMIUM(GLsizeiptr written_size);
RasterCmdHelper* helper_;
std::string last_error_;
gles2::DebugMarkerManager debug_marker_manager_;
......@@ -268,6 +269,8 @@ class RASTER_EXPORT RasterImplementation : public RasterInterface,
mutable base::Lock lost_lock_;
bool lost_;
SkColor background_color_;
DISALLOW_COPY_AND_ASSIGN(RasterImplementation);
};
......
......@@ -754,13 +754,15 @@ struct BeginRasterCHROMIUM {
GLuint _sk_color,
GLuint _msaa_sample_count,
GLboolean _can_use_lcd_text,
GLint _color_type) {
GLint _color_type,
GLuint _color_space_transfer_cache_id) {
SetHeader();
texture_id = _texture_id;
sk_color = _sk_color;
msaa_sample_count = _msaa_sample_count;
can_use_lcd_text = _can_use_lcd_text;
color_type = _color_type;
color_space_transfer_cache_id = _color_space_transfer_cache_id;
}
void* Set(void* cmd,
......@@ -768,10 +770,11 @@ struct BeginRasterCHROMIUM {
GLuint _sk_color,
GLuint _msaa_sample_count,
GLboolean _can_use_lcd_text,
GLint _color_type) {
static_cast<ValueType*>(cmd)->Init(_texture_id, _sk_color,
_msaa_sample_count, _can_use_lcd_text,
_color_type);
GLint _color_type,
GLuint _color_space_transfer_cache_id) {
static_cast<ValueType*>(cmd)->Init(
_texture_id, _sk_color, _msaa_sample_count, _can_use_lcd_text,
_color_type, _color_space_transfer_cache_id);
return NextCmdAddress<ValueType>(cmd);
}
......@@ -781,10 +784,11 @@ struct BeginRasterCHROMIUM {
uint32_t msaa_sample_count;
uint32_t can_use_lcd_text;
int32_t color_type;
uint32_t color_space_transfer_cache_id;
};
static_assert(sizeof(BeginRasterCHROMIUM) == 24,
"size of BeginRasterCHROMIUM should be 24");
static_assert(sizeof(BeginRasterCHROMIUM) == 28,
"size of BeginRasterCHROMIUM should be 28");
static_assert(offsetof(BeginRasterCHROMIUM, header) == 0,
"offset of BeginRasterCHROMIUM header should be 0");
static_assert(offsetof(BeginRasterCHROMIUM, texture_id) == 4,
......@@ -797,6 +801,9 @@ static_assert(offsetof(BeginRasterCHROMIUM, can_use_lcd_text) == 16,
"offset of BeginRasterCHROMIUM can_use_lcd_text should be 16");
static_assert(offsetof(BeginRasterCHROMIUM, color_type) == 20,
"offset of BeginRasterCHROMIUM color_type should be 20");
static_assert(
offsetof(BeginRasterCHROMIUM, color_space_transfer_cache_id) == 24,
"offset of BeginRasterCHROMIUM color_space_transfer_cache_id should be 24");
struct RasterCHROMIUM {
typedef RasterCHROMIUM ValueType;
......
......@@ -248,9 +248,10 @@ TEST_F(RasterFormatTest, LockDiscardableTextureCHROMIUM) {
TEST_F(RasterFormatTest, BeginRasterCHROMIUM) {
cmds::BeginRasterCHROMIUM& cmd = *GetBufferAs<cmds::BeginRasterCHROMIUM>();
void* next_cmd = cmd.Set(&cmd, static_cast<GLuint>(11),
static_cast<GLuint>(12), static_cast<GLuint>(13),
static_cast<GLboolean>(14), static_cast<GLint>(15));
void* next_cmd =
cmd.Set(&cmd, static_cast<GLuint>(11), static_cast<GLuint>(12),
static_cast<GLuint>(13), static_cast<GLboolean>(14),
static_cast<GLint>(15), static_cast<GLuint>(16));
EXPECT_EQ(static_cast<uint32_t>(cmds::BeginRasterCHROMIUM::kCmdId),
cmd.header.command);
EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
......@@ -259,6 +260,7 @@ TEST_F(RasterFormatTest, BeginRasterCHROMIUM) {
EXPECT_EQ(static_cast<GLuint>(13), cmd.msaa_sample_count);
EXPECT_EQ(static_cast<GLboolean>(14), cmd.can_use_lcd_text);
EXPECT_EQ(static_cast<GLint>(15), cmd.color_type);
EXPECT_EQ(static_cast<GLuint>(16), cmd.color_space_transfer_cache_id);
CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
}
......
......@@ -38,7 +38,7 @@ GL_APICALL void GL_APIENTRY glUnlockDiscardableTextureCHROMIUM (GLuint t
GL_APICALL bool GL_APIENTRY glLockDiscardableTextureCHROMIUM (GLuint texture_id);
// Extension CHROMIUM_raster_transport
GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint texture_id, GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, GLint color_type);
GL_APICALL void GL_APIENTRY glBeginRasterCHROMIUM (GLuint texture_id, GLuint sk_color, GLuint msaa_sample_count, GLboolean can_use_lcd_text, GLint color_type, GLuint color_space_transfer_cache_id);
GL_APICALL void GL_APIENTRY glRasterCHROMIUM (GLsizeiptr size, const void* list);
GL_APICALL void GL_APIENTRY glEndRasterCHROMIUM (void);
GL_APICALL void GL_APIENTRY glCreateTransferCacheEntryINTERNAL (GLuint entry_type, GLuint entry_id, GLuint handle_shm_id, GLuint handle_shm_offset, GLuint data_shm_id, GLuint data_shm_offset, GLuint data_size);
......
......@@ -20152,6 +20152,8 @@ error::Error GLES2DecoderImpl::HandleLockDiscardableTextureCHROMIUM(
return error::kNoError;
}
namespace {
class TransferCacheDeserializeHelperImpl
: public cc::TransferCacheDeserializeHelper {
public:
......@@ -20171,6 +20173,8 @@ class TransferCacheDeserializeHelperImpl
ServiceTransferCache* transfer_cache_;
};
} // namespace
void GLES2DecoderImpl::DoBeginRasterCHROMIUM(
GLuint texture_id,
GLuint sk_color,
......
......@@ -15,6 +15,7 @@
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "cc/paint/color_space_transfer_cache_entry.h"
......@@ -51,8 +52,15 @@
#include "gpu/command_buffer/service/service_transfer_cache.h"
#include "gpu/command_buffer/service/vertex_array_manager.h"
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorSpaceXformCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSurfaceProps.h"
#include "third_party/skia/include/core/SkTypeface.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_version_info.h"
#include "ui/gl/init/create_gr_gl_interface.h"
......@@ -527,11 +535,10 @@ class RasterDecoderImpl : public RasterDecoder, public gles2::ErrorStateClient {
GLuint sk_color,
GLuint msaa_sample_count,
GLboolean can_use_lcd_text,
GLint color_type) {
NOTIMPLEMENTED();
}
void DoRasterCHROMIUM(GLsizeiptr size, const void* list) { NOTIMPLEMENTED(); }
void DoEndRasterCHROMIUM() { NOTIMPLEMENTED(); }
GLint color_type,
GLuint color_space_transfer_cache_id);
void DoRasterCHROMIUM(GLsizeiptr size, const void* list);
void DoEndRasterCHROMIUM();
void DoCreateTransferCacheEntryINTERNAL(GLuint entry_type,
GLuint entry_id,
GLuint handle_shm_id,
......@@ -663,6 +670,8 @@ class RasterDecoderImpl : public RasterDecoder, public gles2::ErrorStateClient {
// Raster helpers.
sk_sp<GrContext> gr_context_;
sk_sp<SkSurface> sk_surface_;
std::unique_ptr<SkCanvas> raster_canvas_;
base::WeakPtrFactory<DecoderContext> weak_ptr_factory_;
......@@ -2459,6 +2468,239 @@ bool RasterDecoderImpl::DoBindOrCopyTexImageIfNeeded(Texture* texture,
return false;
}
namespace {
// Helper to read client data from transfer cache.
class TransferCacheDeserializeHelperImpl
: public cc::TransferCacheDeserializeHelper {
public:
explicit TransferCacheDeserializeHelperImpl(
ServiceTransferCache* transfer_cache)
: transfer_cache_(transfer_cache) {
DCHECK(transfer_cache_);
}
~TransferCacheDeserializeHelperImpl() final = default;
private:
cc::ServiceTransferCacheEntry* GetEntryInternal(
cc::TransferCacheEntryType entry_type,
uint32_t entry_id) final {
return transfer_cache_->GetEntry(entry_type, entry_id);
}
ServiceTransferCache* const transfer_cache_;
DISALLOW_COPY_AND_ASSIGN(TransferCacheDeserializeHelperImpl);
};
} // namespace
void RasterDecoderImpl::DoBeginRasterCHROMIUM(
GLuint texture_id,
GLuint sk_color,
GLuint msaa_sample_count,
GLboolean can_use_lcd_text,
GLint color_type,
GLuint color_space_transfer_cache_id) {
if (!gr_context_) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"chromium_raster_transport not enabled via attribs");
return;
}
if (sk_surface_) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"BeginRasterCHROMIUM without EndRasterCHROMIUM");
return;
}
DCHECK(!raster_canvas_);
gr_context_->resetContext();
// This function should look identical to
// ResourceProvider::ScopedSkSurfaceProvider.
GrGLTextureInfo texture_info;
auto* texture_ref = GetTexture(texture_id);
if (!texture_ref) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"unknown texture id");
return;
}
auto* texture = texture_ref->texture();
int width;
int height;
int depth;
if (!texture->GetLevelSize(texture->target(), 0, &width, &height, &depth)) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"missing texture size info");
return;
}
GLenum type;
GLenum internal_format;
if (!texture->GetLevelType(texture->target(), 0, &type, &internal_format)) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"missing texture type info");
return;
}
texture_info.fID = texture_ref->service_id();
texture_info.fTarget = texture->target();
if (texture->target() != GL_TEXTURE_2D &&
texture->target() != GL_TEXTURE_RECTANGLE_ARB) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"invalid texture target");
return;
}
// GetInternalFormat may return a base internal format but Skia requires a
// sized internal format. So this may be adjusted below.
texture_info.fFormat = GetInternalFormat(&gl_version_info(), internal_format);
switch (color_type) {
case kARGB_4444_SkColorType:
if (internal_format != GL_RGBA4 && internal_format != GL_RGBA) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"color type mismatch");
return;
}
if (texture_info.fFormat == GL_RGBA)
texture_info.fFormat = GL_RGBA4;
break;
case kRGBA_8888_SkColorType:
if (internal_format != GL_RGBA8_OES && internal_format != GL_RGBA) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"color type mismatch");
return;
}
if (texture_info.fFormat == GL_RGBA)
texture_info.fFormat = GL_RGBA8_OES;
break;
case kBGRA_8888_SkColorType:
if (internal_format != GL_BGRA_EXT && internal_format != GL_BGRA8_EXT) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"color type mismatch");
return;
}
if (texture_info.fFormat == GL_BGRA_EXT)
texture_info.fFormat = GL_BGRA8_EXT;
if (texture_info.fFormat == GL_RGBA)
texture_info.fFormat = GL_RGBA8_OES;
break;
default:
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"unsupported color type");
return;
}
GrBackendTexture gr_texture(width, height, GrMipMapped::kNo, texture_info);
uint32_t flags = 0;
// Use unknown pixel geometry to disable LCD text.
SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
if (can_use_lcd_text) {
// LegacyFontHost will get LCD text and skia figures out what type to use.
surface_props =
SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
}
SkColorType sk_color_type = static_cast<SkColorType>(color_type);
// If we can't match requested MSAA samples, don't use MSAA.
int final_msaa_count = std::max(static_cast<int>(msaa_sample_count), 0);
if (final_msaa_count >
gr_context_->maxSurfaceSampleCountForColorType(sk_color_type))
final_msaa_count = 0;
sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
gr_context_.get(), gr_texture, kTopLeft_GrSurfaceOrigin, final_msaa_count,
sk_color_type, nullptr, &surface_props);
if (!sk_surface_) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"failed to create surface");
return;
}
TransferCacheDeserializeHelperImpl transfer_cache_deserializer(
transfer_cache_.get());
auto* color_space_entry =
transfer_cache_deserializer
.GetEntryAs<cc::ServiceColorSpaceTransferCacheEntry>(
color_space_transfer_cache_id);
if (!color_space_entry || !color_space_entry->color_space().IsValid()) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"failed to find valid color space");
return;
}
raster_canvas_ = SkCreateColorSpaceXformCanvas(
sk_surface_->getCanvas(),
color_space_entry->color_space().ToSkColorSpace());
// All or nothing clearing, as no way to validate the client's input on what
// is the "used" part of the texture.
if (texture->IsLevelCleared(texture->target(), 0))
return;
// TODO(enne): This doesn't handle the case where the background color
// changes and so any extra pixels outside the raster area that get
// sampled may be incorrect.
raster_canvas_->drawColor(sk_color);
texture_manager()->SetLevelCleared(texture_ref, texture->target(), 0, true);
}
void RasterDecoderImpl::DoRasterCHROMIUM(GLsizeiptr size, const void* list) {
if (!sk_surface_) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glRasterCHROMIUM",
"RasterCHROMIUM without BeginRasterCHROMIUM");
return;
}
DCHECK(transfer_cache_);
alignas(
cc::PaintOpBuffer::PaintOpAlign) char data[sizeof(cc::LargestPaintOp)];
const char* buffer = static_cast<const char*>(list);
SkCanvas* canvas = raster_canvas_.get();
SkMatrix original_ctm;
cc::PlaybackParams playback_params(nullptr, original_ctm);
cc::PaintOp::DeserializeOptions options;
TransferCacheDeserializeHelperImpl impl(transfer_cache_.get());
options.transfer_cache = &impl;
int op_idx = 0;
while (size > 4) {
size_t skip = 0;
cc::PaintOp* deserialized_op = cc::PaintOp::Deserialize(
buffer, size, &data[0], sizeof(cc::LargestPaintOp), &skip, options);
if (!deserialized_op) {
std::string msg =
base::StringPrintf("RasterCHROMIUM: bad op: %i", op_idx);
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glRasterCHROMIUM", msg.c_str());
return;
}
deserialized_op->Raster(canvas, playback_params);
deserialized_op->DestroyThis();
size -= skip;
buffer += skip;
op_idx++;
}
}
void RasterDecoderImpl::DoEndRasterCHROMIUM() {
if (!sk_surface_) {
LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginRasterCHROMIUM",
"EndRasterCHROMIUM without BeginRasterCHROMIUM");
return;
}
raster_canvas_.reset();
sk_surface_->prepareForExternalIO();
sk_surface_.reset();
// It is important to reset state after each RasterCHROMIUM since skia can
// change the GL state which can invalidate the tracking done in this
// decoder.
RestoreState(nullptr);
}
void RasterDecoderImpl::DoCreateTransferCacheEntryINTERNAL(
GLuint raw_entry_type,
GLuint entry_id,
......
......@@ -208,8 +208,11 @@ error::Error RasterDecoderImpl::HandleBeginRasterCHROMIUM(
GLuint msaa_sample_count = static_cast<GLuint>(c.msaa_sample_count);
GLboolean can_use_lcd_text = static_cast<GLboolean>(c.can_use_lcd_text);
GLint color_type = static_cast<GLint>(c.color_type);
GLuint color_space_transfer_cache_id =
static_cast<GLuint>(c.color_space_transfer_cache_id);
DoBeginRasterCHROMIUM(texture_id, sk_color, msaa_sample_count,
can_use_lcd_text, color_type);
can_use_lcd_text, color_type,
color_space_transfer_cache_id);
return error::kNoError;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment