Properly handle extracted bitmaps in cross process/shared addr space SkGPipe.

Use the pixel ref which we have already copied and the appropriate pixel ref
offset.

Turn SampleDrawBitmap into a GM to test this functionality.

Review URL: https://codereview.appspot.com/6348059

git-svn-id: http://skia.googlecode.com/svn/trunk@4417 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
scroggo@google.com 2012-07-02 13:35:09 +00:00
parent 366f1c6a09
commit 4f1f6bf050
4 changed files with 46 additions and 27 deletions

View File

@ -5,12 +5,13 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SampleCode.h"
#include "SkView.h"
#include "gm.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkShader.h"
#include "SkUtils.h"
#include "SkDevice.h"
#include "SkString.h"
namespace skiagm {
static void create_bitmap(SkBitmap* bitmap) {
const int W = 100;
@ -25,22 +26,21 @@ static void create_bitmap(SkBitmap* bitmap) {
canvas.drawCircle(SkIntToScalar(W)/2, SkIntToScalar(H)/2, SkIntToScalar(W)/2, paint);
}
class DrawBitmapView : public SampleView {
SkPath fPath;
class ExtractBitmapGM : public GM {
public:
DrawBitmapView() {}
ExtractBitmapGM() {}
protected:
// overrides from SkEventSink
virtual bool onQuery(SkEvent* evt) {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "DrawBitmap");
return true;
}
return this->INHERITED::onQuery(evt);
virtual SkString onShortName() SK_OVERRIDE {
return SkString("extractbitmap");
}
virtual void onDrawContent(SkCanvas* canvas) {
virtual SkISize onISize() SK_OVERRIDE {
return make_isize(600, 600);
}
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
SkBitmap bitmap;
create_bitmap(&bitmap);
int x = bitmap.width() / 2;
@ -75,10 +75,12 @@ protected:
}
private:
typedef SampleView INHERITED;
typedef GM INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() { return new DrawBitmapView; }
static SkViewRegister reg(MyFactory);
static GM* MyFactory(void*) { return new ExtractBitmapGM; }
static GMRegistry reg(MyFactory);
}

View File

@ -48,7 +48,6 @@
'../samplecode/SampleDegenerateTwoPtRadials.cpp',
'../samplecode/SampleDither.cpp',
'../samplecode/SampleDitherBitmap.cpp',
'../samplecode/SampleDrawBitmap.cpp',
'../samplecode/SampleDrawLooper.cpp',
'../samplecode/SampleEffects.cpp',
'../samplecode/SampleEmboss.cpp',

View File

@ -20,6 +20,7 @@
'../gm/degeneratesegments.cpp',
'../gm/dashing.cpp',
'../gm/drawbitmaprect.cpp',
'../gm/extractbitmap.cpp',
'../gm/emptypath.cpp',
'../gm/filltypes.cpp',
'../gm/filltypespersp.cpp',

View File

@ -81,10 +81,19 @@ public:
* @return void* Pointer to the heap's copy of the bitmap. If NULL,
* the bitmap could not be copied.
*/
const SkBitmap* addBitmap(const SkBitmap& bm) {
const uint32_t genID = bm.getGenerationID();
const SkBitmap* addBitmap(const SkBitmap& orig) {
const uint32_t genID = orig.getGenerationID();
SkPixelRef* sharedPixelRef = NULL;
for (int i = fBitmaps.count() - 1; i >= 0; i--) {
if (genID == fBitmaps[i].fGenID) {
if (orig.pixelRefOffset() != fBitmaps[i].fBitmap->pixelRefOffset()) {
// In this case, the bitmaps share a pixelRef, but have
// different offsets. Keep track of the other bitmap so that
// instead of making another copy of the pixelRef we can use
// the copy we already made.
sharedPixelRef = fBitmaps[i].fBitmap->pixelRef();
break;
}
return fBitmaps[i].fBitmap;
}
}
@ -92,13 +101,21 @@ public:
// If the bitmap is mutable, we still need to do a deep copy, since the
// caller may modify it afterwards. That said, if the bitmap is mutable,
// but has no pixelRef, the copy constructor actually does a deep copy.
if (fCanDoShallowCopies && (bm.isImmutable() || !bm.pixelRef())) {
copy = new SkBitmap(bm);
if (fCanDoShallowCopies && (orig.isImmutable() || !orig.pixelRef())) {
copy = new SkBitmap(orig);
} else {
copy = new SkBitmap();
if (!bm.copyTo(copy, bm.getConfig())) {
delete copy;
return NULL;
if (sharedPixelRef != NULL) {
// Do a shallow copy of the bitmap to get the width, height, etc
copy = new SkBitmap(orig);
// Replace the pixelRef with the copy that was already made, and
// use the appropriate offset.
copy->setPixelRef(sharedPixelRef, orig.pixelRefOffset());
} else {
copy = new SkBitmap();
if (!orig.copyTo(copy, orig.getConfig())) {
delete copy;
return NULL;
}
}
}
BitmapInfo* info = fBitmaps.append();