Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Unified Diff: third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp

Issue 1484853003: Ganesh: images upload to GPU performance fix (skip copying encoded data) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Thread safe reference counting and disposal of shared data (m_data that is) Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index b332fd9d54f678d45843a7c906dc1d3ff6805cb7..2f0da222bf1e9fd1b4dd4a7272945605e2b3478f 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -99,6 +99,7 @@ static bool updateYUVComponentSizes(ImageDecoder* decoder, SkISize componentSize
ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer> data, bool allDataReceived, bool isMultiFrame)
: m_fullSize(fullSize)
+ , m_data(new ThreadSafeDataTransport())
, m_isMultiFrame(isMultiFrame)
, m_decodeFailedAndEmpty(false)
, m_decodeCount(0)
@@ -114,15 +115,50 @@ ImageFrameGenerator::~ImageFrameGenerator()
void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataReceived)
{
- m_data.setData(data.get(), allDataReceived);
+ m_data->setData(data.get(), allDataReceived);
}
-void ImageFrameGenerator::copyData(RefPtr<SharedBuffer>* data, bool* allDataReceived)
+static void sharedBufSkDataReleaseProc(const void* addr, void* ctx)
{
+ ThreadSafeDataTransport* someonesMData = static_cast<ThreadSafeDataTransport*>(ctx);
+ ASSERT(someonesMData);
+ // Deref m_data now.
+ someonesMData->deref();
+}
+
+SkData* ImageFrameGenerator::refSkData()
+{
+ // Every SkData instance and SharedBuffer need to keep buffer->data() refcounted.
+ // Both SkData and m_data.m_readBuffer are having separate ref counting implementations.
+ //
+ // SkData's SkData::NewWithProc is designed with similar use case in mind,
+ // unmapping wrapped shmem data once all SkData instances are disposed.
+ // in this case, sharedBufSkDataReleaseProc would just need to deref (since m_data.m_readBuffer
+ // might still hold a reference) and that is happening in sharedBufSkDataReleaseProc.
+ //
+ // Preventing m_data disposal if ImageFrameGenerator is thread safe - SkData could get disposed
+ // in any thread, and SkData would still need to hold the ref to SharedBuffer if ImageFrameGenerator
+ // is deleted. This is why full m_data (ThreadSafeRefCounted) is passed to client - to hold the
+ // reference to SharedBuffer (accompanying returned SkData). By contract in Skia's SkData,
+ // client needs to call SkData unref that would end up in sharedBufSkDataReleaseProc
+ // releasing the ref to ThreadSafeDataTransport (in thread safe way) and underlying SharedBuffer.
+ //
+ // A note about allDataReceived:
+ // Client side use case is valid only for full image (encoded) data downloaded,
+ // but, incidentally, this is in line with current Chromium implementation, where
+ // DeferredImageDecoder::setData is called only once with allDataReceived and after
+ // that m_data.m_readBuffer.data() is not changed. For the sake of not leaving loose ends,
+ // ThreadSafeDataTransport::data is checking if there is new data added after AllDataReceived
+ // was set to true.
SharedBuffer* buffer = 0;
- m_data.data(&buffer, allDataReceived);
- if (buffer)
- *data = buffer->copy();
+ bool allDataReceived = false;
+ m_data->data(&buffer, &allDataReceived);
+ if (!allDataReceived)
+ return nullptr;
+
+ // While SkData is holding reference to underlying data, prevent disposing m_data and it's content.
scroggo_chromium 2015/12/02 20:15:02 its*
+ m_data->ref();
+ return SkData::NewWithProc(buffer->data(), buffer->size(), sharedBufSkDataReleaseProc, m_data.get());
scroggo_chromium 2015/12/02 20:15:02 What happens if the SharedBuffer's internal Vector
}
bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index, void* pixels, size_t rowBytes)
@@ -182,7 +218,7 @@ bool ImageFrameGenerator::decodeToYUV(SkISize componentSizes[3], void* planes[3]
SharedBuffer* data = 0;
bool allDataReceived = false;
- m_data.data(&data, &allDataReceived);
+ m_data->data(&data, &allDataReceived);
// FIXME: YUV decoding does not currently support progressive decoding.
ASSERT(allDataReceived);
@@ -288,7 +324,7 @@ bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap*
SharedBuffer* data = 0;
bool allDataReceived = false;
bool newDecoder = false;
- m_data.data(&data, &allDataReceived);
+ m_data->data(&data, &allDataReceived);
// Try to create an ImageDecoder if we are not given one.
if (!*decoder) {
@@ -356,7 +392,7 @@ bool ImageFrameGenerator::getYUVComponentSizes(SkISize componentSizes[3])
SharedBuffer* data = 0;
bool allDataReceived = false;
- m_data.data(&data, &allDataReceived);
+ m_data->data(&data, &allDataReceived);
// FIXME: YUV decoding does not currently support progressive decoding.
if (!allDataReceived)

Powered by Google App Engine
This is Rietveld 408576698