aboutsummaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/core/SkBitmap.h3
-rw-r--r--include/core/SkImageInfo.h17
-rw-r--r--include/core/SkPixelRef.h32
-rw-r--r--include/core/SkPixmap.h152
4 files changed, 202 insertions, 2 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index a39c8688ae..144e93ba88 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -11,6 +11,7 @@
#include "SkColor.h"
#include "SkColorTable.h"
#include "SkImageInfo.h"
+#include "SkPixmap.h"
#include "SkPoint.h"
#include "SkRefCnt.h"
@@ -428,6 +429,8 @@ public:
*/
bool lockPixelsAreWritable() const;
+ bool requestLock(SkAutoPixmapUnlock* result) const;
+
/** Call this to be sure that the bitmap is valid enough to be drawn (i.e.
it has non-null pixels, and if required by its colortype, it has a
non-null colortable. Returns true if all of the above are met.
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index 01318fd1aa..daa50dcdb2 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -111,6 +111,17 @@ static inline bool SkColorTypeIsValid(unsigned value) {
return value <= kLastEnum_SkColorType;
}
+static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) {
+ int shift = 0;
+ switch (SkColorTypeBytesPerPixel(ct)) {
+ case 4: shift = 2; break;
+ case 2: shift = 1; break;
+ case 1: shift = 0; break;
+ default: return 0;
+ }
+ return y * rowBytes + (x << shift);
+}
+
///////////////////////////////////////////////////////////////////////////////
/**
@@ -247,6 +258,12 @@ public:
return (size_t)this->minRowBytes64();
}
+ size_t computeOffset(int x, int y, size_t rowBytes) const {
+ SkASSERT((unsigned)x < (unsigned)fWidth);
+ SkASSERT((unsigned)y < (unsigned)fHeight);
+ return SkColorTypeComputeOffset(fColorType, x, y, rowBytes);
+ }
+
bool operator==(const SkImageInfo& other) const {
return 0 == memcmp(this, &other, sizeof(other));
}
diff --git a/include/core/SkPixelRef.h b/include/core/SkPixelRef.h
index 8a1e3db2b6..7c3156ee74 100644
--- a/include/core/SkPixelRef.h
+++ b/include/core/SkPixelRef.h
@@ -10,15 +10,15 @@
#include "SkAtomics.h"
#include "SkBitmap.h"
+#include "SkFilterQuality.h"
#include "SkImageInfo.h"
#include "SkMutex.h"
+#include "SkPixmap.h"
#include "SkRefCnt.h"
#include "SkSize.h"
#include "SkString.h"
#include "SkTDArray.h"
-//#define xed
-
#ifdef SK_DEBUG
/**
* Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref
@@ -193,6 +193,30 @@ public:
return this->onRefEncodedData();
}
+ struct LockRequest {
+ SkISize fSize;
+ SkFilterQuality fQuality;
+ };
+
+ struct LockResult {
+ void (*fUnlockProc)(void* ctx);
+ void* fUnlockContext;
+
+ SkColorTable* fCTable; // should be NULL unless colortype is kIndex8
+ const void* fPixels;
+ size_t fRowBytes;
+ SkISize fSize;
+
+ void unlock() {
+ if (fUnlockProc) {
+ fUnlockProc(fUnlockContext);
+ fUnlockProc = NULL; // can't unlock twice!
+ }
+ }
+ };
+
+ bool requestLock(const LockRequest&, LockResult*);
+
/** Are we really wrapping a texture instead of a bitmap?
*/
virtual GrTexture* getTexture() { return NULL; }
@@ -299,6 +323,8 @@ protected:
*/
virtual size_t getAllocatedSizeInBytes() const;
+ virtual bool onRequestLock(const LockRequest&, LockResult*);
+
/** Return the mutex associated with this pixelref. This value is assigned
in the constructor, and cannot change during the lifetime of the object.
*/
@@ -319,6 +345,8 @@ private:
LockRec fRec;
int fLockCount;
+ bool lockPixelsInsideMutex(LockRec* rec);
+
// Bottom bit indicates the Gen ID is unique.
bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); }
mutable SkAtomic<uint32_t> fTaggedGenID;
diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h
new file mode 100644
index 0000000000..a2ce6cd788
--- /dev/null
+++ b/include/core/SkPixmap.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkPixmap_DEFINED
+#define SkPixmap_DEFINED
+
+#include "SkImageInfo.h"
+
+class SkColorTable;
+
+/**
+ * Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the
+ * lifetime of the pixel memory (nor the colortable if provided).
+ */
+class SkPixmap {
+public:
+ SkPixmap()
+ : fPixels(NULL), fCTable(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0))
+ {}
+
+ SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes,
+ SkColorTable* ctable = NULL)
+ : fPixels(addr), fCTable(ctable), fRowBytes(rowBytes), fInfo(info)
+ {
+ if (kIndex_8_SkColorType == info.colorType()) {
+ SkASSERT(ctable);
+ } else {
+ SkASSERT(NULL == ctable);
+ }
+ }
+
+ const SkImageInfo& info() const { return fInfo; }
+ size_t rowBytes() const { return fRowBytes; }
+ const void* addr() const { return fPixels; }
+ SkColorTable* ctable() const { return fCTable; }
+
+ int width() const { return fInfo.width(); }
+ int height() const { return fInfo.height(); }
+ SkColorType colorType() const { return fInfo.colorType(); }
+ SkAlphaType alphaType() const { return fInfo.alphaType(); }
+ bool isOpaque() const { return fInfo.isOpaque(); }
+
+ int64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); }
+ size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
+
+ const uint32_t* addr32() const {
+ SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType()));
+ return reinterpret_cast<const uint32_t*>(fPixels);
+ }
+
+ const uint16_t* addr16() const {
+ SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType()));
+ return reinterpret_cast<const uint16_t*>(fPixels);
+ }
+
+ const uint8_t* addr8() const {
+ SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType()));
+ return reinterpret_cast<const uint8_t*>(fPixels);
+ }
+
+ const uint32_t* addr32(int x, int y) const {
+ SkASSERT((unsigned)x < (unsigned)fInfo.width());
+ SkASSERT((unsigned)y < (unsigned)fInfo.height());
+ return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2));
+ }
+ const uint16_t* addr16(int x, int y) const {
+ SkASSERT((unsigned)x < (unsigned)fInfo.width());
+ SkASSERT((unsigned)y < (unsigned)fInfo.height());
+ return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1));
+ }
+ const uint8_t* addr8(int x, int y) const {
+ SkASSERT((unsigned)x < (unsigned)fInfo.width());
+ SkASSERT((unsigned)y < (unsigned)fInfo.height());
+ return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0));
+ }
+ const void* addr(int x, int y) const {
+ return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes);
+ }
+
+ // Writable versions
+
+ void* writable_addr() const { return const_cast<void*>(fPixels); }
+ uint32_t* writable_addr32(int x, int y) const {
+ return const_cast<uint32_t*>(this->addr32(x, y));
+ }
+ uint16_t* writable_addr16(int x, int y) const {
+ return const_cast<uint16_t*>(this->addr16(x, y));
+ }
+ uint8_t* writable_addr8(int x, int y) const {
+ return const_cast<uint8_t*>(this->addr8(x, y));
+ }
+
+private:
+ const void* fPixels;
+ SkColorTable* fCTable;
+ size_t fRowBytes;
+ SkImageInfo fInfo;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+class SkAutoPixmapUnlock : ::SkNoncopyable {
+public:
+ SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {}
+ SkAutoPixmapUnlock(const SkPixmap& pm, void (*unlock)(void*), void* ctx)
+ : fUnlockProc(unlock), fUnlockContext(ctx), fPixmap(pm), fIsLocked(true)
+ {}
+ ~SkAutoPixmapUnlock() { this->unlock(); }
+
+ /**
+ * Return the currently locked pixmap. Undefined if it has been unlocked.
+ */
+ const SkPixmap& pixmap() const {
+ SkASSERT(this->isLocked());
+ return fPixmap;
+ }
+
+ bool isLocked() const { return fIsLocked; }
+
+ /**
+ * Unlocks the pixmap. Can safely be called more than once as it will only call the underlying
+ * unlock-proc once.
+ */
+ void unlock() {
+ if (fUnlockProc) {
+ SkASSERT(fIsLocked);
+ fUnlockProc(fUnlockContext);
+ fUnlockProc = NULL;
+ fIsLocked = false;
+ }
+ }
+
+ /**
+ * If there is a currently locked pixmap, unlock it, then copy the specified pixmap
+ * and (optional) unlock proc/context.
+ */
+ void reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx);
+
+private:
+ void (*fUnlockProc)(void*);
+ void* fUnlockContext;
+ SkPixmap fPixmap;
+ bool fIsLocked;
+
+ friend class SkBitmap;
+};
+
+#endif