1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2008 The Android Open Source Project 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef SkPixelRef_DEFINED 9cb93a386Sopenharmony_ci#define SkPixelRef_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 12cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 13cb93a386Sopenharmony_ci#include "include/core/SkPixmap.h" 14cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h" 15cb93a386Sopenharmony_ci#include "include/core/SkSize.h" 16cb93a386Sopenharmony_ci#include "include/private/SkIDChangeListener.h" 17cb93a386Sopenharmony_ci#include "include/private/SkMutex.h" 18cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci#include <atomic> 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_cistruct SkIRect; 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciclass GrTexture; 25cb93a386Sopenharmony_ciclass SkDiscardableMemory; 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ci/** \class SkPixelRef 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci This class is the smart container for pixel memory, and is used with SkBitmap. 30cb93a386Sopenharmony_ci This class can be shared/accessed between multiple threads. 31cb93a386Sopenharmony_ci*/ 32cb93a386Sopenharmony_ciclass SK_API SkPixelRef : public SkRefCnt { 33cb93a386Sopenharmony_cipublic: 34cb93a386Sopenharmony_ci SkPixelRef(int width, int height, void* addr, size_t rowBytes); 35cb93a386Sopenharmony_ci ~SkPixelRef() override; 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ci SkISize dimensions() const { return {fWidth, fHeight}; } 38cb93a386Sopenharmony_ci int width() const { return fWidth; } 39cb93a386Sopenharmony_ci int height() const { return fHeight; } 40cb93a386Sopenharmony_ci void* pixels() const { return fPixels; } 41cb93a386Sopenharmony_ci size_t rowBytes() const { return fRowBytes; } 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci /** Returns a non-zero, unique value corresponding to the pixels in this 44cb93a386Sopenharmony_ci pixelref. Each time the pixels are changed (and notifyPixelsChanged is 45cb93a386Sopenharmony_ci called), a different generation ID will be returned. 46cb93a386Sopenharmony_ci */ 47cb93a386Sopenharmony_ci uint32_t getGenerationID() const; 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci /** 50cb93a386Sopenharmony_ci * Call this if you have changed the contents of the pixels. This will in- 51cb93a386Sopenharmony_ci * turn cause a different generation ID value to be returned from 52cb93a386Sopenharmony_ci * getGenerationID(). 53cb93a386Sopenharmony_ci */ 54cb93a386Sopenharmony_ci void notifyPixelsChanged(); 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci /** Returns true if this pixelref is marked as immutable, meaning that the 57cb93a386Sopenharmony_ci contents of its pixels will not change for the lifetime of the pixelref. 58cb93a386Sopenharmony_ci */ 59cb93a386Sopenharmony_ci bool isImmutable() const { return fMutability != kMutable; } 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci /** Marks this pixelref is immutable, meaning that the contents of its 62cb93a386Sopenharmony_ci pixels will not change for the lifetime of the pixelref. This state can 63cb93a386Sopenharmony_ci be set on a pixelref, but it cannot be cleared once it is set. 64cb93a386Sopenharmony_ci */ 65cb93a386Sopenharmony_ci void setImmutable(); 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci // Register a listener that may be called the next time our generation ID changes. 68cb93a386Sopenharmony_ci // 69cb93a386Sopenharmony_ci // We'll only call the listener if we're confident that we are the only SkPixelRef with this 70cb93a386Sopenharmony_ci // generation ID. If our generation ID changes and we decide not to call the listener, we'll 71cb93a386Sopenharmony_ci // never call it: you must add a new listener for each generation ID change. We also won't call 72cb93a386Sopenharmony_ci // the listener when we're certain no one knows what our generation ID is. 73cb93a386Sopenharmony_ci // 74cb93a386Sopenharmony_ci // This can be used to invalidate caches keyed by SkPixelRef generation ID. 75cb93a386Sopenharmony_ci // Takes ownership of listener. Threadsafe. 76cb93a386Sopenharmony_ci void addGenIDChangeListener(sk_sp<SkIDChangeListener> listener); 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache 79cb93a386Sopenharmony_ci // to know automatically those entries can be purged when this pixelref is changed or deleted. 80cb93a386Sopenharmony_ci void notifyAddedToCache() { 81cb93a386Sopenharmony_ci fAddedToCache.store(true); 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return nullptr; } 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ciprotected: 87cb93a386Sopenharmony_ci void android_only_reset(int width, int height, size_t rowBytes); 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ciprivate: 90cb93a386Sopenharmony_ci int fWidth; 91cb93a386Sopenharmony_ci int fHeight; 92cb93a386Sopenharmony_ci void* fPixels; 93cb93a386Sopenharmony_ci size_t fRowBytes; 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci // Bottom bit indicates the Gen ID is unique. 96cb93a386Sopenharmony_ci bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); } 97cb93a386Sopenharmony_ci mutable std::atomic<uint32_t> fTaggedGenID; 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ci SkIDChangeListener::List fGenIDChangeListeners; 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci // Set true by caches when they cache content that's derived from the current pixels. 102cb93a386Sopenharmony_ci std::atomic<bool> fAddedToCache; 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci enum Mutability { 105cb93a386Sopenharmony_ci kMutable, // PixelRefs begin mutable. 106cb93a386Sopenharmony_ci kTemporarilyImmutable, // Considered immutable, but can revert to mutable. 107cb93a386Sopenharmony_ci kImmutable, // Once set to this state, it never leaves. 108cb93a386Sopenharmony_ci } fMutability : 8; // easily fits inside a byte 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci void needsNewGenID(); 111cb93a386Sopenharmony_ci void callGenIDChangeListeners(); 112cb93a386Sopenharmony_ci 113cb93a386Sopenharmony_ci void setTemporarilyImmutable(); 114cb93a386Sopenharmony_ci void restoreMutability(); 115cb93a386Sopenharmony_ci friend class SkSurface_Raster; // For the two methods above. 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci void setImmutableWithID(uint32_t genID); 118cb93a386Sopenharmony_ci friend void SkBitmapCache_setImmutableWithID(SkPixelRef*, uint32_t); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci using INHERITED = SkRefCnt; 121cb93a386Sopenharmony_ci}; 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_ci#endif 124