Chromium Code Reviews| Index: src/core/SkPixelRef.cpp |
| diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp |
| index e7f5c8d94720f8870109d7923bf9056b968f1545..90e2a40ea4fb92513d4ba351a366ec330ba2b207 100644 |
| --- a/src/core/SkPixelRef.cpp |
| +++ b/src/core/SkPixelRef.cpp |
| @@ -172,27 +172,48 @@ void SkPixelRef::setPreLocked(void* pixels, size_t rowBytes, SkColorTable* ctabl |
| #endif |
| } |
| +bool SkPixelRef::lockPixelsInsideMutex(LockRec* rec) { |
| + fMutex->assertHeld(); |
| + |
| + // For historical reasons, we always inc fLockCount, even if we return false. |
| + // It would be nice to change this (it seems), and only inc if we actually succeed... |
| + if (1 == ++fLockCount) { |
| + SkASSERT(fRec.isZero()); |
| + |
| + LockRec rec; |
| + if (!this->onNewLockPixels(&rec)) { |
| + fLockCount -= 1; // we return fLockCount unchanged if we fail. |
| + return false; |
| + } |
| + SkASSERT(!rec.isZero()); // else why did onNewLock return true? |
| + fRec = rec; |
| + } |
| + *rec = fRec; |
| + return true; |
| +} |
| + |
| bool SkPixelRef::lockPixels(LockRec* rec) { |
| SkASSERT(!fPreLocked || SKPIXELREF_PRELOCKED_LOCKCOUNT == fLockCount); |
| - if (!fPreLocked) { |
| + if (fPreLocked) { |
| + *rec = fRec; |
| + return true; |
| + } else { |
| TRACE_EVENT_BEGIN0("skia", "SkPixelRef::lockPixelsMutex"); |
| SkAutoMutexAcquire ac(*fMutex); |
| TRACE_EVENT_END0("skia", "SkPixelRef::lockPixelsMutex"); |
| - |
| - if (1 == ++fLockCount) { |
| - SkASSERT(fRec.isZero()); |
| - |
| - LockRec rec; |
| - if (!this->onNewLockPixels(&rec)) { |
| - return false; |
| - } |
| - SkASSERT(!rec.isZero()); // else why did onNewLock return true? |
| - fRec = rec; |
| + SkDEBUGCODE(int oldCount = fLockCount;) |
| + bool success = this->lockPixelsInsideMutex(rec); |
| + // lockPixelsInsideMutex only increments the count if it succeeds. |
| + SkASSERT(oldCount + (int)success == fLockCount); |
| + |
| + if (!success) { |
| + // For compatibility with SkBitmap calling lockPixels, we still want to increment |
| + // fLockCount even if we failed. If we updated SkBitmap we could remove this oddity. |
| + fLockCount += 1; |
| } |
| + return success; |
| } |
| - *rec = fRec; |
| - return true; |
| } |
| bool SkPixelRef::lockPixels() { |
| @@ -219,6 +240,26 @@ void SkPixelRef::unlockPixels() { |
| } |
| } |
| +bool SkPixelRef::requestLock(const LockRequest& request, LockResult* result) { |
| + SkASSERT(result); |
| + if (request.fSize.isEmpty()) { |
| + return false; |
| + } |
| + |
| + if (fPreLocked) { |
| + result->fUnlockProc = NULL; |
| + result->fUnlockContext = NULL; |
| + result->fCTable = fRec.fColorTable; |
| + result->fPixels = fRec.fPixels; |
| + result->fRowBytes = fRec.fRowBytes; |
| + result->fSize.set(fInfo.width(), fInfo.height()); |
| + return true; |
| + } else { |
| + SkAutoMutexAcquire ac(*fMutex); |
| + return this->onRequestLock(request, result); |
| + } |
| +} |
| + |
| bool SkPixelRef::lockPixelsAreWritable() const { |
| return this->onLockPixelsAreWritable(); |
| } |
| @@ -291,6 +332,8 @@ bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) { |
| return this->onReadPixels(dst, subset); |
| } |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) { |
| return false; |
| } |
| @@ -308,3 +351,23 @@ size_t SkPixelRef::getAllocatedSizeInBytes() const { |
| return 0; |
| } |
| +static void unlock_legacy_result(void* ctx) { |
| + SkPixelRef* pr = (SkPixelRef*)ctx; |
| + pr->unlockPixels(); |
| + pr->unref(); // balancing the Ref in onRequestLoc |
|
scroggo
2015/05/22 15:04:14
onRequestLock*
|
| +} |
| + |
| +bool SkPixelRef::onRequestLock(const LockRequest& request, LockResult* result) { |
| + LockRec rec; |
| + if (!this->lockPixelsInsideMutex(&rec)) { |
| + return false; |
| + } |
| + |
| + result->fUnlockProc = unlock_legacy_result; |
| + result->fUnlockContext = SkRef(this); // this is balanced in our fUnlockProc |
| + result->fCTable = rec.fColorTable; |
| + result->fPixels = rec.fPixels; |
| + result->fRowBytes = rec.fRowBytes; |
| + result->fSize.set(fInfo.width(), fInfo.height()); |
| + return true; |
| +} |