1/* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "core/platform/graphics/chromium/DiscardablePixelRef.h" 28 29#include "public/platform/Platform.h" 30#include "wtf/StdLibExtras.h" 31 32namespace WebCore { 33 34namespace { 35 36// URI label for a discardable SkPixelRef. 37const char labelDiscardable[] = "discardable"; 38 39} // namespace 40 41 42bool DiscardablePixelRefAllocator::allocPixelRef(SkBitmap* dst, SkColorTable* ctable) 43{ 44 // It should not be possible to have a non-null color table in Blink. 45 ASSERT(!ctable); 46 47 Sk64 size = dst->getSize64(); 48 if (size.isNeg() || !size.is32()) 49 return false; 50 51 SkAutoTUnref<DiscardablePixelRef> pixelRef(new DiscardablePixelRef(adoptPtr(new SkMutex()))); 52 if (pixelRef->allocAndLockDiscardableMemory(size.get32())) { 53 pixelRef->setURI(labelDiscardable); 54 dst->setPixelRef(pixelRef.get()); 55 // This method is only called when a DiscardablePixelRef is created to back a SkBitmap. 56 // It is necessary to lock this SkBitmap to have a valid pointer to pixels. Otherwise, 57 // this SkBitmap could be assigned to another SkBitmap and locking/unlocking the other 58 // SkBitmap will make this one losing its pixels. 59 dst->lockPixels(); 60 return true; 61 } 62 63 // Fallback to heap allocator if discardable memory is not available. 64 return dst->allocPixels(); 65} 66 67DiscardablePixelRef::DiscardablePixelRef(PassOwnPtr<SkMutex> mutex) 68 : SkPixelRef(mutex.get()) 69 , m_lockedMemory(0) 70 , m_mutex(mutex) 71{ 72} 73 74DiscardablePixelRef::~DiscardablePixelRef() 75{ 76} 77 78bool DiscardablePixelRef::allocAndLockDiscardableMemory(size_t bytes) 79{ 80 m_discardable = adoptPtr(WebKit::Platform::current()->allocateAndLockDiscardableMemory(bytes)); 81 if (m_discardable) { 82 m_lockedMemory = m_discardable->data(); 83 return true; 84 } 85 return false; 86} 87 88void* DiscardablePixelRef::onLockPixels(SkColorTable** ctable) 89{ 90 if (!m_lockedMemory && m_discardable->lock()) 91 m_lockedMemory = m_discardable->data(); 92 93 *ctable = 0; 94 return m_lockedMemory; 95} 96 97void DiscardablePixelRef::onUnlockPixels() 98{ 99 if (m_lockedMemory) 100 m_discardable->unlock(); 101 m_lockedMemory = 0; 102} 103 104bool DiscardablePixelRef::isDiscardable(SkPixelRef* pixelRef) 105{ 106 // FIXME: DEFINE_STATIC_LOCAL is not thread safe. 107 // ImageDecodingStore provides the synchronization for this. 108 DEFINE_STATIC_LOCAL(const SkString, discardable, (labelDiscardable)); 109 return pixelRef && pixelRef->getURI() && discardable.equals(pixelRef->getURI()); 110} 111 112} // namespace WebCore 113