add pixelref->readPixels()
unimplemented (for now) on the gpu side git-svn-id: http://skia.googlecode.com/svn/trunk@1037 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
5d561959dc
commit
50dfa0130b
@ -20,7 +20,9 @@
|
|||||||
#include "SkRefCnt.h"
|
#include "SkRefCnt.h"
|
||||||
#include "SkString.h"
|
#include "SkString.h"
|
||||||
|
|
||||||
|
class SkBitmap;
|
||||||
class SkColorTable;
|
class SkColorTable;
|
||||||
|
struct SkIRect;
|
||||||
class SkMutex;
|
class SkMutex;
|
||||||
class SkFlattenableReadBuffer;
|
class SkFlattenableReadBuffer;
|
||||||
class SkFlattenableWriteBuffer;
|
class SkFlattenableWriteBuffer;
|
||||||
@ -112,6 +114,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual SkGpuTexture* getTexture() { return NULL; }
|
virtual SkGpuTexture* getTexture() { return NULL; }
|
||||||
|
|
||||||
|
bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL);
|
||||||
|
|
||||||
// serialization
|
// serialization
|
||||||
|
|
||||||
typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
|
typedef SkPixelRef* (*Factory)(SkFlattenableReadBuffer&);
|
||||||
@ -157,6 +161,14 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void onUnlockPixels() = 0;
|
virtual void onUnlockPixels() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For pixelrefs that don't have access to their raw pixels, they may be
|
||||||
|
* able to make a copy of them (e.g. if the pixels are on the GPU).
|
||||||
|
*
|
||||||
|
* The base class implementation returns false;
|
||||||
|
*/
|
||||||
|
virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subsetOrNull);
|
||||||
|
|
||||||
/** Return the mutex associated with this pixelref. This value is assigned
|
/** Return the mutex associated with this pixelref. This value is assigned
|
||||||
in the constructor, and cannot change during the lifetime of the object.
|
in the constructor, and cannot change during the lifetime of the object.
|
||||||
*/
|
*/
|
||||||
|
@ -40,6 +40,7 @@ protected:
|
|||||||
|
|
||||||
// override from SkPixelRef
|
// override from SkPixelRef
|
||||||
virtual void onUnlockPixels() {}
|
virtual void onUnlockPixels() {}
|
||||||
|
virtual bool onReadPixels(SkBitmap* dst, const SkIRect* subset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrTexture* fTexture;
|
GrTexture* fTexture;
|
||||||
|
@ -865,61 +865,82 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we have a texture, first get those pixels
|
||||||
|
SkBitmap tmpSrc;
|
||||||
|
const SkBitmap* src = this;
|
||||||
|
|
||||||
|
if (this->getTexture()) {
|
||||||
|
if (!fPixelRef->readPixels(&tmpSrc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SkASSERT(tmpSrc.width() == this->width());
|
||||||
|
SkASSERT(tmpSrc.height() == this->height());
|
||||||
|
|
||||||
|
// did we get lucky and we can just return tmpSrc?
|
||||||
|
if (tmpSrc.config() == dstConfig && NULL == alloc) {
|
||||||
|
dst->swap(tmpSrc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall through to the raster case
|
||||||
|
src = &tmpSrc;
|
||||||
|
}
|
||||||
|
|
||||||
// we lock this now, since we may need its colortable
|
// we lock this now, since we may need its colortable
|
||||||
SkAutoLockPixels srclock(*this);
|
SkAutoLockPixels srclock(*src);
|
||||||
if (!this->readyToDraw()) {
|
if (!src->readyToDraw()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkBitmap tmp;
|
SkBitmap tmpDst;
|
||||||
tmp.setConfig(dstConfig, this->width(), this->height());
|
tmpDst.setConfig(dstConfig, src->width(), src->height());
|
||||||
|
|
||||||
// allocate colortable if srcConfig == kIndex8_Config
|
// allocate colortable if srcConfig == kIndex8_Config
|
||||||
SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
|
SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
|
||||||
new SkColorTable(*this->getColorTable()) : NULL;
|
new SkColorTable(*src->getColorTable()) : NULL;
|
||||||
SkAutoUnref au(ctable);
|
SkAutoUnref au(ctable);
|
||||||
if (!tmp.allocPixels(alloc, ctable)) {
|
if (!tmpDst.allocPixels(alloc, ctable)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkAutoLockPixels dstlock(tmp);
|
SkAutoLockPixels dstlock(tmpDst);
|
||||||
if (!tmp.readyToDraw()) {
|
if (!tmpDst.readyToDraw()) {
|
||||||
// allocator/lock failed
|
// allocator/lock failed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do memcpy for the same configs cases, else use drawing
|
/* do memcpy for the same configs cases, else use drawing
|
||||||
*/
|
*/
|
||||||
if (this->config() == dstConfig) {
|
if (src->config() == dstConfig) {
|
||||||
if (tmp.getSize() == this->getSize()) {
|
if (tmpDst.getSize() == src->getSize()) {
|
||||||
memcpy(tmp.getPixels(), this->getPixels(), this->getSafeSize());
|
memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
|
||||||
} else {
|
} else {
|
||||||
const char* srcP = reinterpret_cast<const char*>(this->getPixels());
|
const char* srcP = reinterpret_cast<const char*>(src->getPixels());
|
||||||
char* dstP = reinterpret_cast<char*>(tmp.getPixels());
|
char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
|
||||||
// to be sure we don't read too much, only copy our logical pixels
|
// to be sure we don't read too much, only copy our logical pixels
|
||||||
size_t bytesToCopy = tmp.width() * tmp.bytesPerPixel();
|
size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
|
||||||
for (int y = 0; y < tmp.height(); y++) {
|
for (int y = 0; y < tmpDst.height(); y++) {
|
||||||
memcpy(dstP, srcP, bytesToCopy);
|
memcpy(dstP, srcP, bytesToCopy);
|
||||||
srcP += this->rowBytes();
|
srcP += src->rowBytes();
|
||||||
dstP += tmp.rowBytes();
|
dstP += tmpDst.rowBytes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if the src has alpha, we have to clear the dst first
|
// if the src has alpha, we have to clear the dst first
|
||||||
if (!this->isOpaque()) {
|
if (!src->isOpaque()) {
|
||||||
tmp.eraseColor(0);
|
tmpDst.eraseColor(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkCanvas canvas(tmp);
|
SkCanvas canvas(tmpDst);
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
|
|
||||||
paint.setDither(true);
|
paint.setDither(true);
|
||||||
canvas.drawBitmap(*this, 0, 0, &paint);
|
canvas.drawBitmap(*src, 0, 0, &paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp.setIsOpaque(this->isOpaque());
|
tmpDst.setIsOpaque(src->isOpaque());
|
||||||
|
|
||||||
dst->swap(tmp);
|
dst->swap(tmpDst);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,14 @@ void SkPixelRef::setImmutable() {
|
|||||||
fIsImmutable = true;
|
fIsImmutable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
|
||||||
|
return this->onReadPixels(dst, subset);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define MAX_PAIR_COUNT 16
|
#define MAX_PAIR_COUNT 16
|
||||||
|
@ -27,4 +27,7 @@ SkGrTexturePixelRef::~SkGrTexturePixelRef() {
|
|||||||
GrSafeUnref(fTexture);
|
GrSafeUnref(fTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user