Commit d2b1fb18 authored by Thiabaud Engelbrecht's avatar Thiabaud Engelbrecht Committed by Chromium LUCI CQ

[blink] Move SkRWBuffer to blink from skia.

This is not used anywhere in skia, so we are adding it to blink. Another
CL deletes this from skia.

This code was originally called SkRWBuffer, and was written by reed@.

The only semantic changes to this code made here is disallowing copying
and assigning of RWBuffer, neither of which happens in blink.

Bug: 1151405
Change-Id: I035b53f8bc8ab0829bce9bb73c46a5dd95ca65ab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2551847
Commit-Queue: Thiabaud Engelbrecht <thiabaud@google.com>
Reviewed-by: default avatarJeremy Roman <jbroman@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarMike Reed <reed@google.com>
Cr-Commit-Position: refs/heads/master@{#832682}
parent 9579fa45
...@@ -1108,6 +1108,8 @@ component("platform") { ...@@ -1108,6 +1108,8 @@ component("platform") {
"graphics/raster_dark_mode_filter_impl.h", "graphics/raster_dark_mode_filter_impl.h",
"graphics/replaying_canvas.cc", "graphics/replaying_canvas.cc",
"graphics/replaying_canvas.h", "graphics/replaying_canvas.h",
"graphics/rw_buffer.cc",
"graphics/rw_buffer.h",
"graphics/scoped_interpolation_quality.h", "graphics/scoped_interpolation_quality.h",
"graphics/scrollbar_theme_settings.cc", "graphics/scrollbar_theme_settings.cc",
"graphics/scrollbar_theme_settings.h", "graphics/scrollbar_theme_settings.h",
...@@ -2017,6 +2019,7 @@ source_set("blink_platform_unittests_sources") { ...@@ -2017,6 +2019,7 @@ source_set("blink_platform_unittests_sources") {
"graphics/path_test.cc", "graphics/path_test.cc",
"graphics/placeholder_image_test.cc", "graphics/placeholder_image_test.cc",
"graphics/raster_dark_mode_filter_impl_test.cc", "graphics/raster_dark_mode_filter_impl_test.cc",
"graphics/rw_buffer_test.cc",
"graphics/video_frame_submitter_test.cc", "graphics/video_frame_submitter_test.cc",
"heap_observer_set_test.cc", "heap_observer_set_test.cc",
"image-decoders/bmp/bmp_image_decoder_test.cc", "image-decoders/bmp/bmp_image_decoder_test.cc",
......
...@@ -77,4 +77,7 @@ specific_include_rules = { ...@@ -77,4 +77,7 @@ specific_include_rules = {
"graphics_context.h": [ "graphics_context.h": [
"+third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h", "+third_party/blink/public/mojom/frame/frame_owner_properties.mojom-blink.h",
], ],
"rw_buffer_test.cc": [
"+base/threading/platform_thread.h",
],
} }
...@@ -190,9 +190,9 @@ sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator() { ...@@ -190,9 +190,9 @@ sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator() {
DCHECK_GT(decoded_size.width(), 0); DCHECK_GT(decoded_size.width(), 0);
DCHECK_GT(decoded_size.height(), 0); DCHECK_GT(decoded_size.height(), 0);
sk_sp<SkROBuffer> ro_buffer(rw_buffer_->makeROBufferSnapshot()); sk_sp<ROBuffer> ro_buffer(rw_buffer_->MakeROBufferSnapshot());
scoped_refptr<SegmentReader> segment_reader = scoped_refptr<SegmentReader> segment_reader =
SegmentReader::CreateFromSkROBuffer(std::move(ro_buffer)); SegmentReader::CreateFromROBuffer(std::move(ro_buffer));
SkImageInfo info = SkImageInfo info =
SkImageInfo::MakeN32(decoded_size.width(), decoded_size.height(), SkImageInfo::MakeN32(decoded_size.width(), decoded_size.height(),
...@@ -251,12 +251,12 @@ sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator() { ...@@ -251,12 +251,12 @@ sk_sp<PaintImageGenerator> DeferredImageDecoder::CreateGenerator() {
scoped_refptr<SharedBuffer> DeferredImageDecoder::Data() { scoped_refptr<SharedBuffer> DeferredImageDecoder::Data() {
if (!rw_buffer_) if (!rw_buffer_)
return nullptr; return nullptr;
sk_sp<SkROBuffer> ro_buffer(rw_buffer_->makeROBufferSnapshot()); sk_sp<ROBuffer> ro_buffer(rw_buffer_->MakeROBufferSnapshot());
scoped_refptr<SharedBuffer> shared_buffer = SharedBuffer::Create(); scoped_refptr<SharedBuffer> shared_buffer = SharedBuffer::Create();
SkROBuffer::Iter it(ro_buffer.get()); ROBuffer::Iter it(ro_buffer.get());
do { do {
shared_buffer->Append(static_cast<const char*>(it.data()), it.size()); shared_buffer->Append(static_cast<const char*>(it.data()), it.size());
} while (it.next()); } while (it.Next());
return shared_buffer; return shared_buffer;
} }
...@@ -279,13 +279,13 @@ void DeferredImageDecoder::SetDataInternal(scoped_refptr<SharedBuffer> data, ...@@ -279,13 +279,13 @@ void DeferredImageDecoder::SetDataInternal(scoped_refptr<SharedBuffer> data,
if (frame_generator_) { if (frame_generator_) {
if (!rw_buffer_) if (!rw_buffer_)
rw_buffer_ = std::make_unique<SkRWBuffer>(data->size()); rw_buffer_ = std::make_unique<RWBuffer>(data->size());
for (auto it = data->GetIteratorAt(rw_buffer_->size()); it != data->cend(); for (auto it = data->GetIteratorAt(rw_buffer_->size()); it != data->cend();
++it) { ++it) {
DCHECK_GE(data->size(), rw_buffer_->size() + it->size()); DCHECK_GE(data->size(), rw_buffer_->size() + it->size());
const size_t remaining = data->size() - rw_buffer_->size() - it->size(); const size_t remaining = data->size() - rw_buffer_->size() - it->size();
rw_buffer_->append(it->data(), it->size(), remaining); rw_buffer_->Append(it->data(), it->size(), remaining);
} }
} }
} }
......
...@@ -31,13 +31,13 @@ ...@@ -31,13 +31,13 @@
#include "base/macros.h" #include "base/macros.h"
#include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/geometry/int_size.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/graphics/rw_buffer.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder.h" #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
#include "third_party/skia/include/core/SkRWBuffer.h"
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
namespace blink { namespace blink {
...@@ -104,7 +104,7 @@ class PLATFORM_EXPORT DeferredImageDecoder final { ...@@ -104,7 +104,7 @@ class PLATFORM_EXPORT DeferredImageDecoder final {
// Copy of the data that is passed in, used by deferred decoding. // Copy of the data that is passed in, used by deferred decoding.
// Allows creating readonly snapshots that may be read in another thread. // Allows creating readonly snapshots that may be read in another thread.
std::unique_ptr<SkRWBuffer> rw_buffer_; std::unique_ptr<RWBuffer> rw_buffer_;
std::unique_ptr<ImageDecoder> metadata_decoder_; std::unique_ptr<ImageDecoder> metadata_decoder_;
String filename_extension_; String filename_extension_;
...@@ -141,4 +141,4 @@ class PLATFORM_EXPORT DeferredImageDecoder final { ...@@ -141,4 +141,4 @@ class PLATFORM_EXPORT DeferredImageDecoder final {
} // namespace blink } // namespace blink
#endif #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DEFERRED_IMAGE_DECODER_H_
This diff is collapsed.
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_RW_BUFFER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_RW_BUFFER_H_
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkRefCnt.h"
class SkStreamAsset;
namespace blink {
class ROBuffer;
/**
* Accumulates bytes of memory that are "appended" to it, growing internal
* storage as needed. The growth is done such that at any time in the writer's
* thread, an ROBuffer or StreamAsset can be snapped off (and safely passed to
* another thread). The ROBuffer/StreamAsset snapshot can see the previously
* stored bytes, but will be unaware of any future writes.
*/
class PLATFORM_EXPORT RWBuffer {
public:
struct BufferHead;
struct BufferBlock;
explicit RWBuffer(size_t initialCapacity = 0);
~RWBuffer();
RWBuffer& operator=(const RWBuffer&) = delete;
RWBuffer(const RWBuffer&) = delete;
size_t size() const { return total_used_; }
/**
* Append |length| bytes from |buffer|.
*
* If the caller knows in advance how much more data they are going to
* append, they can pass a |reserve| hint (representing the number of upcoming
* bytes *in addition* to the current append), to minimize the number of
* internal allocations.
*/
void Append(const void* buffer, size_t length, size_t reserve = 0);
sk_sp<ROBuffer> MakeROBufferSnapshot() const;
std::unique_ptr<SkStreamAsset> MakeStreamSnapshot() const;
void Validate() const;
private:
BufferHead* head_ = nullptr;
BufferBlock* tail_ = nullptr;
size_t total_used_ = 0;
};
/**
* Contains a read-only, thread-sharable block of memory. To access the memory,
* the caller must instantiate a local iterator, as the memory is stored in 1 or
* more contiguous blocks.
*/
class PLATFORM_EXPORT ROBuffer : public SkRefCnt {
public:
/**
* Return the logical length of the data owned/shared by this buffer. It may
* be stored in multiple contiguous blocks, accessible via the iterator.
*/
size_t size() const { return available_; }
class PLATFORM_EXPORT Iter {
public:
explicit Iter(const ROBuffer*);
explicit Iter(const sk_sp<ROBuffer>&);
void Reset(const ROBuffer*);
/**
* Return the current continuous block of memory, or nullptr if the
* iterator is exhausted
*/
const void* data() const;
/**
* Returns the number of bytes in the current contiguous block of memory,
* or 0 if the iterator is exhausted.
*/
size_t size() const;
/**
* Advance to the next contiguous block of memory, returning true if there
* is another block, or false if the iterator is exhausted.
*/
bool Next();
private:
const RWBuffer::BufferBlock* block_;
size_t remaining_;
const ROBuffer* buffer_;
};
private:
ROBuffer(const RWBuffer::BufferHead* head,
size_t available,
const RWBuffer::BufferBlock* tail);
~ROBuffer() override;
const RWBuffer::BufferHead* head_;
const size_t available_;
const RWBuffer::BufferBlock* tail_;
friend class RWBuffer;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_RW_BUFFER_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/graphics/rw_buffer.h"
#include <array>
#include "base/threading/platform_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkStream.h"
namespace blink {
namespace {
const char gABC[] = "abcdefghijklmnopqrstuvwxyz";
void check_abcs(const char buffer[], size_t size) {
ASSERT_EQ(size % 26, 0u);
for (size_t offset = 0; offset < size; offset += 26) {
EXPECT_TRUE(!memcmp(&buffer[offset], gABC, 26));
}
}
// stream should contain an integral number of copies of gABC.
void check_alphabet_stream(SkStream* stream) {
ASSERT_TRUE(stream->hasLength());
size_t size = stream->getLength();
ASSERT_EQ(size % 26, 0u);
std::vector<char> storage(size);
char* array = storage.data();
size_t bytesRead = stream->read(array, size);
EXPECT_EQ(bytesRead, size);
check_abcs(array, size);
// try checking backwards
for (size_t offset = size; offset > 0; offset -= 26) {
EXPECT_TRUE(stream->seek(offset - 26));
EXPECT_EQ(stream->getPosition(), offset - 26);
EXPECT_EQ(stream->read(array, 26), 26u);
check_abcs(array, 26);
EXPECT_EQ(stream->getPosition(), offset);
}
}
// reader should contains an integral number of copies of gABC.
void check_alphabet_buffer(const ROBuffer* reader) {
size_t size = reader->size();
ASSERT_EQ(size % 26, 0u);
std::vector<char> storage(size);
ROBuffer::Iter iter(reader);
size_t offset = 0;
do {
ASSERT_LE(offset + iter.size(), size);
memcpy(storage.data() + offset, iter.data(), iter.size());
offset += iter.size();
} while (iter.Next());
ASSERT_EQ(offset, size);
check_abcs(storage.data(), size);
}
class ROBufferTestThread : public base::PlatformThread::Delegate {
public:
ROBufferTestThread(sk_sp<ROBuffer> reader, SkStream* stream, size_t i)
: reader_(reader), stream_(stream), i_(i) {}
ROBufferTestThread() = default;
ROBufferTestThread(const ROBufferTestThread&) = default;
void ThreadMain() override {
EXPECT_EQ((i_ + 1) * 26U, reader_->size());
EXPECT_EQ(stream_->getLength(), reader_->size());
check_alphabet_buffer(reader_.get());
check_alphabet_stream(stream_);
EXPECT_TRUE(stream_->rewind());
delete stream_;
}
sk_sp<ROBuffer> reader_;
SkStream* stream_;
size_t i_;
};
} // namespace
TEST(RWBuffer, reporter) {
// Knowing that the default capacity is 4096, choose N large enough so we
// force it to use multiple buffers internally.
static constexpr size_t N = 1000;
std::array<sk_sp<ROBuffer>, N> readers;
std::array<std::unique_ptr<SkStream>, N> streams;
{
RWBuffer buffer;
for (size_t i = 0; i < N; ++i) {
buffer.Append(gABC, 26);
readers[i] = buffer.MakeROBufferSnapshot();
streams[i] = buffer.MakeStreamSnapshot();
}
EXPECT_EQ(N * 26, buffer.size());
}
// Verify that although the RWBuffer's destructor has run, the readers are
// still valid.
for (size_t i = 0; i < N; ++i) {
EXPECT_EQ((i + 1) * 26U, readers[i]->size());
check_alphabet_buffer(readers[i].get());
check_alphabet_stream(streams[i].get());
}
}
TEST(RWBuffer_threaded, reporter) {
// Knowing that the default capacity is 4096, choose N large enough so we
// force it to use multiple buffers internally.
constexpr size_t N = 1000;
RWBuffer buffer;
std::array<ROBufferTestThread, N> threads;
std::array<base::PlatformThreadHandle, N> handlers;
for (size_t i = 0; i < N; ++i) {
buffer.Append(gABC, 26);
sk_sp<ROBuffer> reader = buffer.MakeROBufferSnapshot();
SkStream* stream = buffer.MakeStreamSnapshot().release();
EXPECT_EQ(reader->size(), buffer.size());
EXPECT_EQ(stream->getLength(), buffer.size());
// reader's copy constructor will ref the ROBuffer, which will be unreffed
// when the task ends.
// Ownership of stream is passed to the task, which will delete it.
threads[i] = ROBufferTestThread(reader, stream, i);
ASSERT_TRUE(base::PlatformThread::Create(0, &threads[i], &handlers[i]));
}
EXPECT_EQ(N * 26, buffer.size());
for (size_t i = 0; i < N; ++i) {
base::PlatformThread::Join(handlers[i]);
}
}
// Tests that it is safe to call ROBuffer::Iter::size() when exhausted.
TEST(RWBuffer_size, r) {
RWBuffer buffer;
buffer.Append(gABC, 26);
sk_sp<ROBuffer> roBuffer(buffer.MakeROBufferSnapshot());
ROBuffer::Iter iter(roBuffer.get());
EXPECT_TRUE(iter.data());
EXPECT_EQ(iter.size(), 26u);
// There is only one block in this buffer.
EXPECT_TRUE(!iter.Next());
EXPECT_EQ(0u, iter.size());
}
// Tests that operations (including the destructor) are safe on an RWBuffer
// without any data appended.
TEST(RWBuffer_noAppend, r) {
RWBuffer buffer;
ASSERT_EQ(0u, buffer.size());
sk_sp<ROBuffer> roBuffer = buffer.MakeROBufferSnapshot();
ASSERT_TRUE(roBuffer);
if (roBuffer) {
EXPECT_EQ(roBuffer->size(), 0u);
ROBuffer::Iter iter(roBuffer.get());
EXPECT_EQ(iter.size(), 0u);
EXPECT_TRUE(!iter.data());
EXPECT_TRUE(!iter.Next());
}
std::unique_ptr<SkStream> stream(buffer.MakeStreamSnapshot());
EXPECT_TRUE(stream);
if (stream) {
EXPECT_TRUE(stream->hasLength());
EXPECT_EQ(stream->getLength(), 0u);
EXPECT_EQ(stream->skip(10), 0u);
}
}
} // namespace blink
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
*/ */
#include "third_party/blink/renderer/platform/image-decoders/fast_shared_buffer_reader.h" #include "third_party/blink/renderer/platform/image-decoders/fast_shared_buffer_reader.h"
#include "third_party/blink/renderer/platform/graphics/rw_buffer.h"
#include "third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.h" #include "third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.h"
#include "third_party/blink/renderer/platform/image-decoders/segment_reader.h" #include "third_party/blink/renderer/platform/image-decoders/segment_reader.h"
#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkRWBuffer.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -42,14 +42,14 @@ namespace { ...@@ -42,14 +42,14 @@ namespace {
scoped_refptr<SegmentReader> CopyToROBufferSegmentReader( scoped_refptr<SegmentReader> CopyToROBufferSegmentReader(
scoped_refptr<SegmentReader> input) { scoped_refptr<SegmentReader> input) {
SkRWBuffer rw_buffer; RWBuffer rw_buffer;
const char* segment = nullptr; const char* segment = nullptr;
size_t position = 0; size_t position = 0;
while (size_t length = input->GetSomeData(segment, position)) { while (size_t length = input->GetSomeData(segment, position)) {
rw_buffer.append(segment, length); rw_buffer.Append(segment, length);
position += length; position += length;
} }
return SegmentReader::CreateFromSkROBuffer(rw_buffer.makeROBufferSnapshot()); return SegmentReader::CreateFromROBuffer(rw_buffer.MakeROBufferSnapshot());
} }
scoped_refptr<SegmentReader> CopyToDataSegmentReader( scoped_refptr<SegmentReader> CopyToDataSegmentReader(
...@@ -60,7 +60,7 @@ scoped_refptr<SegmentReader> CopyToDataSegmentReader( ...@@ -60,7 +60,7 @@ scoped_refptr<SegmentReader> CopyToDataSegmentReader(
struct SegmentReaders { struct SegmentReaders {
scoped_refptr<SegmentReader> segment_readers[3]; scoped_refptr<SegmentReader> segment_readers[3];
SegmentReaders(scoped_refptr<SharedBuffer> input) { explicit SegmentReaders(scoped_refptr<SharedBuffer> input) {
segment_readers[0] = segment_readers[0] =
SegmentReader::CreateFromSharedBuffer(std::move(input)); SegmentReader::CreateFromSharedBuffer(std::move(input));
segment_readers[1] = CopyToROBufferSegmentReader(segment_readers[0]); segment_readers[1] = CopyToROBufferSegmentReader(segment_readers[0]);
...@@ -201,21 +201,21 @@ TEST(SegmentReaderTest, variableSegments) { ...@@ -201,21 +201,21 @@ TEST(SegmentReaderTest, variableSegments) {
scoped_refptr<SegmentReader> segment_reader; scoped_refptr<SegmentReader> segment_reader;
{ {
// Create a SegmentReader with difference sized segments, to test that // Create a SegmentReader with difference sized segments, to test that
// the SkROBuffer implementation works when two consecutive segments // the ROBuffer implementation works when two consecutive segments
// are not the same size. This test relies on knowledge of the // are not the same size. This test relies on knowledge of the
// internals of SkRWBuffer: it ensures that each segment is at least // internals of RWBuffer: it ensures that each segment is at least
// 4096 (though the actual data may be smaller, if it has not been // 4096 (though the actual data may be smaller, if it has not been
// written to yet), but when appending a larger amount it may create a // written to yet), but when appending a larger amount it may create a
// larger segment. // larger segment.
SkRWBuffer rw_buffer; RWBuffer rw_buffer;
rw_buffer.append(reference_data, SharedBuffer::kSegmentSize); rw_buffer.Append(reference_data, SharedBuffer::kSegmentSize);
rw_buffer.append(reference_data + SharedBuffer::kSegmentSize, rw_buffer.Append(reference_data + SharedBuffer::kSegmentSize,
2 * SharedBuffer::kSegmentSize); 2 * SharedBuffer::kSegmentSize);
rw_buffer.append(reference_data + 3 * SharedBuffer::kSegmentSize, rw_buffer.Append(reference_data + 3 * SharedBuffer::kSegmentSize,
.5 * SharedBuffer::kSegmentSize); .5 * SharedBuffer::kSegmentSize);
segment_reader = segment_reader =
SegmentReader::CreateFromSkROBuffer(rw_buffer.makeROBufferSnapshot()); SegmentReader::CreateFromROBuffer(rw_buffer.MakeROBufferSnapshot());
} }
const char* segment; const char* segment;
......
...@@ -9,11 +9,11 @@ ...@@ -9,11 +9,11 @@
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/graphics/rw_buffer.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
#include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h"
#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkRWBuffer.h"
namespace blink { namespace blink {
...@@ -103,23 +103,23 @@ sk_sp<SkData> DataSegmentReader::GetAsSkData() const { ...@@ -103,23 +103,23 @@ sk_sp<SkData> DataSegmentReader::GetAsSkData() const {
class ROBufferSegmentReader final : public SegmentReader { class ROBufferSegmentReader final : public SegmentReader {
public: public:
explicit ROBufferSegmentReader(sk_sp<SkROBuffer>); explicit ROBufferSegmentReader(sk_sp<ROBuffer>);
size_t size() const override; size_t size() const override;
size_t GetSomeData(const char*& data, size_t position) const override; size_t GetSomeData(const char*& data, size_t position) const override;
sk_sp<SkData> GetAsSkData() const override; sk_sp<SkData> GetAsSkData() const override;
private: private:
sk_sp<SkROBuffer> ro_buffer_; sk_sp<ROBuffer> ro_buffer_;
mutable Mutex read_mutex_; mutable Mutex read_mutex_;
// Position of the first char in the current block of iter_. // Position of the first char in the current block of iter_.
mutable size_t position_of_block_ GUARDED_BY(read_mutex_); mutable size_t position_of_block_ GUARDED_BY(read_mutex_);
mutable SkROBuffer::Iter iter_ GUARDED_BY(read_mutex_); mutable ROBuffer::Iter iter_ GUARDED_BY(read_mutex_);
DISALLOW_COPY_AND_ASSIGN(ROBufferSegmentReader); DISALLOW_COPY_AND_ASSIGN(ROBufferSegmentReader);
}; };
ROBufferSegmentReader::ROBufferSegmentReader(sk_sp<SkROBuffer> buffer) ROBufferSegmentReader::ROBufferSegmentReader(sk_sp<ROBuffer> buffer)
: ro_buffer_(std::move(buffer)), : ro_buffer_(std::move(buffer)),
position_of_block_(0), position_of_block_(0),
iter_(ro_buffer_.get()) {} iter_(ro_buffer_.get()) {}
...@@ -136,8 +136,8 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data, ...@@ -136,8 +136,8 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data,
MutexLocker lock(read_mutex_); MutexLocker lock(read_mutex_);
if (position < position_of_block_) { if (position < position_of_block_) {
// SkROBuffer::Iter only iterates forwards. Start from the beginning. // ROBuffer::Iter only iterates forwards. Start from the beginning.
iter_.reset(ro_buffer_.get()); iter_.Reset(ro_buffer_.get());
position_of_block_ = 0; position_of_block_ = 0;
} }
...@@ -153,9 +153,9 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data, ...@@ -153,9 +153,9 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data,
} }
// Move to next block. // Move to next block.
if (!iter_.next()) { if (!iter_.Next()) {
// Reset to the beginning, so future calls can succeed. // Reset to the beginning, so future calls can succeed.
iter_.reset(ro_buffer_.get()); iter_.Reset(ro_buffer_.get());
position_of_block_ = 0; position_of_block_ = 0;
return 0; return 0;
} }
...@@ -165,7 +165,7 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data, ...@@ -165,7 +165,7 @@ size_t ROBufferSegmentReader::GetSomeData(const char*& data,
} }
static void UnrefROBuffer(const void* ptr, void* context) { static void UnrefROBuffer(const void* ptr, void* context) {
static_cast<SkROBuffer*>(context)->unref(); static_cast<ROBuffer*>(context)->unref();
} }
sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const { sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const {
...@@ -173,9 +173,9 @@ sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const { ...@@ -173,9 +173,9 @@ sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const {
return nullptr; return nullptr;
// Check to see if the data is already contiguous. // Check to see if the data is already contiguous.
SkROBuffer::Iter iter(ro_buffer_.get()); ROBuffer::Iter iter(ro_buffer_.get());
const bool multiple_blocks = iter.next(); const bool multiple_blocks = iter.Next();
iter.reset(ro_buffer_.get()); iter.Reset(ro_buffer_.get());
if (!multiple_blocks) { if (!multiple_blocks) {
// Contiguous data. No need to copy. // Contiguous data. No need to copy.
...@@ -190,7 +190,7 @@ sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const { ...@@ -190,7 +190,7 @@ sk_sp<SkData> ROBufferSegmentReader::GetAsSkData() const {
size_t size = iter.size(); size_t size = iter.size();
memcpy(dst, iter.data(), size); memcpy(dst, iter.data(), size);
dst += size; dst += size;
} while (iter.next()); } while (iter.Next());
return data; return data;
} }
...@@ -206,8 +206,8 @@ scoped_refptr<SegmentReader> SegmentReader::CreateFromSkData( ...@@ -206,8 +206,8 @@ scoped_refptr<SegmentReader> SegmentReader::CreateFromSkData(
return base::AdoptRef(new DataSegmentReader(std::move(data))); return base::AdoptRef(new DataSegmentReader(std::move(data)));
} }
scoped_refptr<SegmentReader> SegmentReader::CreateFromSkROBuffer( scoped_refptr<SegmentReader> SegmentReader::CreateFromROBuffer(
sk_sp<SkROBuffer> buffer) { sk_sp<ROBuffer> buffer) {
return base::AdoptRef(new ROBufferSegmentReader(std::move(buffer))); return base::AdoptRef(new ROBufferSegmentReader(std::move(buffer)));
} }
......
...@@ -12,19 +12,20 @@ ...@@ -12,19 +12,20 @@
#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h" #include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
class SkData; class SkData;
class SkROBuffer;
template <typename T> template <typename T>
class sk_sp; class sk_sp;
namespace blink { namespace blink {
class ROBuffer;
// Interface that looks like SharedBuffer. Used by ImageDecoders to use various // Interface that looks like SharedBuffer. Used by ImageDecoders to use various
// sources of input including: // sources of input including:
// - SharedBuffer // - SharedBuffer
// - for when the caller already has a SharedBuffer // - for when the caller already has a SharedBuffer
// - SkData // - SkData
// - for when the caller already has an SkData // - for when the caller already has an SkData
// - SkROBuffer // - ROBuffer
// - for when the caller wants to read/write in different threads // - for when the caller wants to read/write in different threads
// //
// Unlike SharedBuffer, this is a read-only interface. There is no way to // Unlike SharedBuffer, this is a read-only interface. There is no way to
...@@ -40,7 +41,7 @@ class PLATFORM_EXPORT SegmentReader ...@@ -40,7 +41,7 @@ class PLATFORM_EXPORT SegmentReader
// These versions use thread-safe input, so they are always thread-safe. // These versions use thread-safe input, so they are always thread-safe.
static scoped_refptr<SegmentReader> CreateFromSkData(sk_sp<SkData>); static scoped_refptr<SegmentReader> CreateFromSkData(sk_sp<SkData>);
static scoped_refptr<SegmentReader> CreateFromSkROBuffer(sk_sp<SkROBuffer>); static scoped_refptr<SegmentReader> CreateFromROBuffer(sk_sp<ROBuffer>);
SegmentReader() = default; SegmentReader() = default;
virtual ~SegmentReader() = default; virtual ~SegmentReader() = default;
......
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