SkCachingPixelRef.cpp revision e5ea500d4714a7d84de2bf913e81be3b65d2de68
1/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkCachingPixelRef.h"
9#include "SkBitmapCache.h"
10
11bool SkCachingPixelRef::Install(SkImageGenerator* generator,
12                                SkBitmap* dst) {
13    SkImageInfo info;
14    SkASSERT(dst != NULL);
15    if ((NULL == generator)
16        || !(generator->getInfo(&info))
17        || !dst->setInfo(info)) {
18        SkDELETE(generator);
19        return false;
20    }
21    SkAutoTUnref<SkCachingPixelRef> ref(SkNEW_ARGS(SkCachingPixelRef,
22                                           (info, generator, dst->rowBytes())));
23    dst->setPixelRef(ref);
24    return true;
25}
26
27SkCachingPixelRef::SkCachingPixelRef(const SkImageInfo& info,
28                                     SkImageGenerator* generator,
29                                     size_t rowBytes)
30    : INHERITED(info)
31    , fImageGenerator(generator)
32    , fErrorInDecoding(false)
33    , fRowBytes(rowBytes) {
34    SkASSERT(fImageGenerator != NULL);
35}
36SkCachingPixelRef::~SkCachingPixelRef() {
37    SkDELETE(fImageGenerator);
38    // Assert always unlock before unref.
39}
40
41bool SkCachingPixelRef::onNewLockPixels(LockRec* rec) {
42    if (fErrorInDecoding) {
43        return false;  // don't try again.
44    }
45
46    const SkImageInfo& info = this->info();
47    if (!SkBitmapCache::Find(this->getGenerationID(), info.width(), info.height(), &fLockedBitmap)) {
48        // Cache has been purged, must re-decode.
49        if (!fLockedBitmap.tryAllocPixels(info, fRowBytes)) {
50            fErrorInDecoding = true;
51            return false;
52        }
53        if (!fImageGenerator->getPixels(info, fLockedBitmap.getPixels(), fRowBytes)) {
54            fErrorInDecoding = true;
55            return false;
56        }
57        fLockedBitmap.setImmutable();
58        SkBitmapCache::Add(this->getGenerationID(), info.width(), info.height(), fLockedBitmap);
59    }
60
61    // Now bitmap should contain a concrete PixelRef of the decoded image.
62    void* pixels = fLockedBitmap.getPixels();
63    SkASSERT(pixels != NULL);
64    rec->fPixels = pixels;
65    rec->fColorTable = NULL;
66    rec->fRowBytes = fLockedBitmap.rowBytes();
67    return true;
68}
69
70void SkCachingPixelRef::onUnlockPixels() {
71    fLockedBitmap.reset();
72}
73