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

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: process comment #101 and rebase to latest 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 0230e474f4411dec576b02d6f865cad892eb5c7c..39a11f9ea619244d84ebd18df4dbbdba22cfbd6d 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -27,6 +27,7 @@
#include "platform/graphics/ImageFrameGenerator.h"
+#include "SkData.h"
#include "platform/SharedBuffer.h"
#include "platform/TraceEvent.h"
#include "platform/graphics/ImageDecodingStore.h"
@@ -101,30 +102,77 @@ static bool updateYUVComponentSizes(ImageDecoder* decoder, SkISize componentSize
ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer> data, bool allDataReceived, bool isMultiFrame)
: m_fullSize(fullSize)
+ , m_data(adoptRef(new ThreadSafeDataTransport()))
, m_isMultiFrame(isMultiFrame)
, m_decodeFailedAndEmpty(false)
, m_decodeCount(0)
, m_frameCount(0)
+ , m_encodedData(nullptr)
{
setData(data.get(), allDataReceived);
}
ImageFrameGenerator::~ImageFrameGenerator()
{
+ if (m_encodedData)
+ m_encodedData->unref();
ImageDecodingStore::instance().removeCacheIndexedByGenerator(this);
}
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 sharedSkDataReleaseCallback(const void* address, void* context)
{
+ // This gets called when m_encodedData reference count becomes 0 - and it could happen in
+ // ImageFrameGenerator destructor or later when m_encodedData gets dereferenced.
+ // In this method, we deref ThreadSafeDataTransport, as ThreadSafeDataTransport is the owner
+ // of data returned via refEncodedData.
+
+ ThreadSafeDataTransport* dataTransport = static_cast<ThreadSafeDataTransport*>(context);
+#if ENABLE(ASSERT)
+ ASSERT(dataTransport);
SharedBuffer* buffer = 0;
- m_data.data(&buffer, allDataReceived);
- if (buffer)
- *data = buffer->copy();
+ bool allDataReceived = false;
+ dataTransport->data(&buffer, &allDataReceived);
+ ASSERT(allDataReceived && buffer && buffer->data() == address);
+#endif
+ // Dereference m_data now.
+ dataTransport->deref();
+}
+
+SkData* ImageFrameGenerator::refEncodedData()
+{
+ // SkData is returned only when full image (encoded) data is received. This is important
+ // since DeferredImageDecoder::setData is called only once with allDataReceived set to true,
+ // and after that m_data->m_readBuffer.data() is not changed. See also RELEASE_ASSERT used in
+ // ThreadSafeDataTransport::data().
+ SharedBuffer* buffer = 0;
+ bool allDataReceived = false;
+ m_data->data(&buffer, &allDataReceived);
+ if (!allDataReceived)
+ return nullptr;
+
+ {
+ // Prevents concurrent access to m_encodedData creation.
+ MutexLocker lock(m_decodeMutex);
+ if (m_encodedData) {
+ m_encodedData->ref();
+ return m_encodedData;
+ }
+ // m_encodedData is created with initial reference count == 1. ImageFrameGenerator always holds one
+ // reference to m_encodedData, as it prevents write access in SkData::writable_data.
+ m_encodedData = SkData::NewWithProc(buffer->data(), buffer->size(), sharedSkDataReleaseCallback, m_data.get());
+ // While m_encodedData is referenced, prevent disposing m_data and its content.
+ // it is dereferenced in sharedSkDataReleaseCallback, called when m_encodedData gets dereferenced.
+ m_data->ref();
+ }
+ // Increase the reference, caller must decrease it. One reference is always kept by ImageFrameGenerator and released
+ // in destructor.
+ m_encodedData->ref();
+ return m_encodedData;
}
bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index, void* pixels, size_t rowBytes)
@@ -184,7 +232,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);
@@ -290,7 +338,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) {
@@ -358,7 +406,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