Chromium Code Reviews| 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..2008789f737b4624135fd6a3629ab5c028fa38d6 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp |
| @@ -117,12 +117,44 @@ void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataRec |
| m_data.setData(data.get(), allDataReceived); |
| } |
| -void ImageFrameGenerator::copyData(RefPtr<SharedBuffer>* data, bool* allDataReceived) |
| +static void sharedBufSkDataReleaseProc(const void* addr, void* ctx) |
| { |
| + SharedBuffer* buffer = static_cast<SharedBuffer*>(ctx); |
| + ASSERT(buffer && buffer->data() == addr); |
| + // Deref SharedBuffer shared with m_data. |
| + buffer->deref(); |
|
Stephen White
2015/12/02 16:15:14
Are we 100% sure this is thread-safe? Does this ca
chrishtr
2015/12/02 16:44:28
It's not clear to me why removing the RefPtr for t
Stephen White
2015/12/02 18:25:47
There's an explicit call to ref() in refSkData() b
chrishtr
2015/12/02 18:26:44
Ah I see, thanks.
|
| +} |
| + |
| +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. |
| + // |
| + // If m_data gets disposed, SkData would still need to hold the ref to SharedBuffer, |
| + // and that is why SharedBuffer (accompanying returned SkData) is passed to client of this |
| + // call - by contract they need to call SkData unref that would end up in sharedBufSkDataReleaseProc |
| + // releasing the ref to 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; |
| + |
| + buffer->ref(); |
|
aleksandar.stojiljkovic
2015/12/02 16:58:24
I'll cover this with comment that the buffer->ref(
|
| + return SkData::NewWithProc(buffer->data(), buffer->size(), sharedBufSkDataReleaseProc, buffer); |
| } |
| bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index, void* pixels, size_t rowBytes) |