Replace SkPicture(SkStream) constructors with a factory.
SkPicture: Remove the constructors which take an SkStream as an argument. Rather than having to check a variable for success, the factory will return NULL on failure. Add a protected function for determining if an SkStream is an SKP to share code with SkTimedPicture. In the factory, check for a NULL SkStream. Use a default decoder (from BUG: https://code.google.com/p/skia/issues/detail?id=1325) SkDebuggerGUI: Call SkPicture::CreateFromStream when necessary. Write a factory for creating SkTimedPictures and use it. Use the factory throughout tools. Add include/lazy to utils and effects gyp include_dirs so SkPicture.h can reference SkImageDecoder.h which references SkBitmapFactory.h (in include/lazy). Changes code Chromium uses, so this will require a temporary Skia and then a change to Chromium to use the new Skia code. TODO: Create a decoder that does nothing to be used by pinspect, lua pictures, etc, and allow it to not assert in SkOrderedReadBuffer. R=reed@google.com Review URL: https://codereview.chromium.org/17113004 git-svn-id: http://skia.googlecode.com/svn/trunk@9822 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
925cdca805
commit
f1754ec691
@ -237,35 +237,24 @@ private:
|
||||
// Wrap SkPicture to allow installation of an SkTimedPicturePlayback object
|
||||
class SkTimedPicture : public SkPicture {
|
||||
public:
|
||||
explicit SkTimedPicture(SkStream* stream, bool* success, SkPicture::InstallPixelRefProc proc,
|
||||
const SkTDArray<bool>& deletedCommands) {
|
||||
if (success) {
|
||||
*success = false;
|
||||
}
|
||||
fRecord = NULL;
|
||||
fPlayback = NULL;
|
||||
fWidth = fHeight = 0;
|
||||
|
||||
static SkTimedPicture* CreateTimedPicture(SkStream* stream,
|
||||
SkPicture::InstallPixelRefProc proc,
|
||||
const SkTDArray<bool>& deletedCommands) {
|
||||
SkPictInfo info;
|
||||
|
||||
if (!stream->read(&info, sizeof(info))) {
|
||||
return;
|
||||
}
|
||||
if (SkPicture::PICTURE_VERSION != info.fVersion) {
|
||||
return;
|
||||
if (!StreamIsSKP(stream, &info)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkTimedPicturePlayback* playback;
|
||||
// Check to see if there is a playback to recreate.
|
||||
if (stream->readBool()) {
|
||||
fPlayback = SkNEW_ARGS(SkTimedPicturePlayback,
|
||||
(stream, info, proc, deletedCommands));
|
||||
playback = SkNEW_ARGS(SkTimedPicturePlayback,
|
||||
(stream, info, proc, deletedCommands));
|
||||
} else {
|
||||
playback = NULL;
|
||||
}
|
||||
|
||||
// do this at the end, so that they will be zero if we hit an error.
|
||||
fWidth = info.fWidth;
|
||||
fHeight = info.fHeight;
|
||||
if (success) {
|
||||
*success = true;
|
||||
}
|
||||
return SkNEW_ARGS(SkTimedPicture, (playback, info.fWidth, info.fHeight));
|
||||
}
|
||||
|
||||
void resetTimes() { ((SkTimedPicturePlayback*) fPlayback)->resetTimes(); }
|
||||
@ -282,6 +271,9 @@ public:
|
||||
private:
|
||||
// disallow default ctor b.c. we don't have a good way to setup the fPlayback ptr
|
||||
SkTimedPicture();
|
||||
// Private ctor only used by CreateTimedPicture, which has created the playback.
|
||||
SkTimedPicture(SkTimedPicturePlayback* playback, int width, int height)
|
||||
: INHERITED(playback, width, height) {}
|
||||
// disallow the copy ctor - enabling would require copying code from SkPicture
|
||||
SkTimedPicture(const SkTimedPicture& src);
|
||||
|
||||
@ -338,10 +330,9 @@ void SkDebuggerGUI::actionProfile() {
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
SkTimedPicture picture(&inputStream, &success, &SkImageDecoder::DecodeMemory,
|
||||
fSkipCommands);
|
||||
if (!success) {
|
||||
SkAutoTUnref<SkTimedPicture> picture(SkTimedPicture::CreateTimedPicture(&inputStream,
|
||||
&SkImageDecoder::DecodeMemory, fSkipCommands));
|
||||
if (NULL == picture.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -377,20 +368,20 @@ void SkDebuggerGUI::actionProfile() {
|
||||
|
||||
static const int kNumRepeats = 10;
|
||||
|
||||
run(&picture, renderer, kNumRepeats);
|
||||
run(picture.get(), renderer, kNumRepeats);
|
||||
|
||||
SkASSERT(picture.count() == fListWidget.count());
|
||||
SkASSERT(picture->count() == fListWidget.count());
|
||||
|
||||
// extract the individual command times from the SkTimedPlaybackPicture
|
||||
for (int i = 0; i < picture.count(); ++i) {
|
||||
double temp = picture.time(i);
|
||||
for (int i = 0; i < picture->count(); ++i) {
|
||||
double temp = picture->time(i);
|
||||
|
||||
QListWidgetItem* item = fListWidget.item(i);
|
||||
|
||||
item->setData(Qt::UserRole + 4, 100.0*temp);
|
||||
}
|
||||
|
||||
setupOverviewText(picture.typeTimes(), picture.totTime(), kNumRepeats);
|
||||
setupOverviewText(picture->typeTimes(), picture->totTime(), kNumRepeats);
|
||||
}
|
||||
|
||||
void SkDebuggerGUI::actionCancel() {
|
||||
@ -905,12 +896,9 @@ void SkDebuggerGUI::loadPicture(const SkString& fileName) {
|
||||
fLoading = true;
|
||||
SkStream* stream = SkNEW_ARGS(SkFILEStream, (fileName.c_str()));
|
||||
|
||||
bool success = false;
|
||||
SkPicture* picture = SkPicture::CreateFromStream(stream);
|
||||
|
||||
SkPicture* picture = SkNEW_ARGS(SkPicture,
|
||||
(stream, &success, &SkImageDecoder::DecodeMemory));
|
||||
|
||||
if (!success) {
|
||||
if (NULL == picture) {
|
||||
QMessageBox::critical(this, "Error loading file", "Couldn't read file, sorry.");
|
||||
SkSafeUnref(stream);
|
||||
return;
|
||||
|
@ -1025,10 +1025,7 @@ public:
|
||||
//@todo thudson 22 April 2011 when can we safely delete [] dst?
|
||||
storage.copyTo(dst);
|
||||
SkMemoryStream pictReadback(dst, streamSize);
|
||||
bool success;
|
||||
// Pass a decoding bitmap function so that the factory GM (which has an SkBitmap with
|
||||
// encoded data) does not fail.
|
||||
SkPicture* retval = new SkPicture (&pictReadback, &success, &SkImageDecoder::DecodeMemory);
|
||||
SkPicture* retval = SkPicture::CreateFromStream(&pictReadback);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
# Gyp file for effects
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
@ -12,6 +13,7 @@
|
||||
'../include/config',
|
||||
'../include/core',
|
||||
'../include/effects',
|
||||
'../include/lazy',
|
||||
'../include/utils',
|
||||
'../src/core',
|
||||
],
|
||||
|
@ -1,3 +1,4 @@
|
||||
# Gyp for utils.
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
@ -10,6 +11,7 @@
|
||||
'../include/core',
|
||||
'../include/effects',
|
||||
'../include/images',
|
||||
'../include/lazy',
|
||||
'../include/pipe',
|
||||
'../include/utils',
|
||||
'../include/utils/mac',
|
||||
|
@ -11,6 +11,7 @@
|
||||
#define SkPicture_DEFINED
|
||||
|
||||
#include "SkBitmap.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkBBoxHierarchy;
|
||||
@ -22,6 +23,8 @@ class SkPictureRecord;
|
||||
class SkStream;
|
||||
class SkWStream;
|
||||
|
||||
struct SkPictInfo;
|
||||
|
||||
/** \class SkPicture
|
||||
|
||||
The SkPicture class records the drawing commands made to a canvas, to
|
||||
@ -41,13 +44,6 @@ public:
|
||||
*/
|
||||
SkPicture(const SkPicture& src);
|
||||
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
* On failure, silently creates an empty picture.
|
||||
* @param SkStream Serialized picture data.
|
||||
*/
|
||||
explicit SkPicture(SkStream*);
|
||||
|
||||
/**
|
||||
* Function signature defining a function that sets up an SkBitmap from encoded data. On
|
||||
* success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set.
|
||||
@ -64,12 +60,13 @@ public:
|
||||
/**
|
||||
* Recreate a picture that was serialized into a stream.
|
||||
* @param SkStream Serialized picture data.
|
||||
* @param success Output parameter. If non-NULL, will be set to true if the picture was
|
||||
* deserialized successfully and false otherwise.
|
||||
* @param proc Function pointer for installing pixelrefs on SkBitmaps representing the
|
||||
* encoded bitmap data from the stream.
|
||||
* @return A new SkPicture representing the serialized data, or NULL if the stream is
|
||||
* invalid.
|
||||
*/
|
||||
SkPicture(SkStream*, bool* success, InstallPixelRefProc proc);
|
||||
static SkPicture* CreateFromStream(SkStream*,
|
||||
InstallPixelRefProc proc = &SkImageDecoder::DecodeMemory);
|
||||
|
||||
virtual ~SkPicture();
|
||||
|
||||
@ -220,13 +217,20 @@ protected:
|
||||
SkPictureRecord* fRecord;
|
||||
int fWidth, fHeight;
|
||||
|
||||
// Create a new SkPicture from an existing SkPicturePlayback. Ref count of
|
||||
// playback is unchanged.
|
||||
SkPicture(SkPicturePlayback*, int width, int height);
|
||||
|
||||
// For testing. Derived classes may instantiate an alternate
|
||||
// SkBBoxHierarchy implementation
|
||||
virtual SkBBoxHierarchy* createBBoxHierarchy() const;
|
||||
|
||||
// Return true if the SkStream represents a serialized picture, and fills out
|
||||
// SkPictInfo. After this function returns, the SkStream is not rewound; it
|
||||
// will be ready to be parsed to create an SkPicturePlayback.
|
||||
// If false is returned, SkPictInfo is unmodified.
|
||||
static bool StreamIsSKP(SkStream*, SkPictInfo*);
|
||||
private:
|
||||
void initFromStream(SkStream*, bool* success, InstallPixelRefProc);
|
||||
|
||||
friend class SkFlatPicture;
|
||||
friend class SkPicturePlayback;
|
||||
|
||||
|
@ -1379,8 +1379,10 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
|
||||
SkAutoDataUnref data(ostream.copyToData());
|
||||
SkMemoryStream istream(data->data(), data->size());
|
||||
SkPicture pict(&istream);
|
||||
orig->drawPicture(pict);
|
||||
SkAutoTUnref<SkPicture> pict(SkPicture::CreateFromStream(&istream));
|
||||
if (pict.get() != NULL) {
|
||||
orig->drawPicture(*pict.get());
|
||||
}
|
||||
} else {
|
||||
fPicture->draw(orig);
|
||||
fPicture->unref();
|
||||
|
@ -48,7 +48,7 @@ class PictFileView : public SampleView {
|
||||
} else {
|
||||
SkFILEStream stream(path);
|
||||
if (stream.isValid()) {
|
||||
pic = SkNEW_ARGS(SkPicture, (&stream, NULL, &SkImageDecoder::DecodeMemory));
|
||||
pic = SkPicture::CreateFromStream(&stream);
|
||||
} else {
|
||||
SkDebugf("coun't load picture at \"path\"\n", path);
|
||||
}
|
||||
|
@ -264,41 +264,47 @@ void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) {
|
||||
|
||||
#include "SkStream.h"
|
||||
|
||||
SkPicture::SkPicture(SkStream* stream) {
|
||||
this->initFromStream(stream, NULL, NULL);
|
||||
}
|
||||
|
||||
SkPicture::SkPicture(SkStream* stream, bool* success, InstallPixelRefProc proc) {
|
||||
this->initFromStream(stream, success, proc);
|
||||
}
|
||||
|
||||
void SkPicture::initFromStream(SkStream* stream, bool* success, InstallPixelRefProc proc) {
|
||||
if (success) {
|
||||
*success = false;
|
||||
bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
|
||||
if (NULL == stream) {
|
||||
return false;
|
||||
}
|
||||
fRecord = NULL;
|
||||
fPlayback = NULL;
|
||||
fWidth = fHeight = 0;
|
||||
|
||||
SkPictInfo info;
|
||||
|
||||
if (!stream->read(&info, sizeof(info))) {
|
||||
return;
|
||||
if (!stream->read(&info, sizeof(SkPictInfo))) {
|
||||
return false;
|
||||
}
|
||||
if (PICTURE_VERSION != info.fVersion) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pInfo != NULL) {
|
||||
*pInfo = info;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height)
|
||||
: fPlayback(playback)
|
||||
, fRecord(NULL)
|
||||
, fWidth(width)
|
||||
, fHeight(height) {}
|
||||
|
||||
SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) {
|
||||
SkPictInfo info;
|
||||
|
||||
if (!StreamIsSKP(stream, &info)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SkPicturePlayback* playback;
|
||||
// Check to see if there is a playback to recreate.
|
||||
if (stream->readBool()) {
|
||||
fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream, info, proc));
|
||||
playback = SkNEW_ARGS(SkPicturePlayback, (stream, info, proc));
|
||||
} else {
|
||||
playback = NULL;
|
||||
}
|
||||
|
||||
// do this at the end, so that they will be zero if we hit an error.
|
||||
fWidth = info.fWidth;
|
||||
fHeight = info.fHeight;
|
||||
if (success) {
|
||||
*success = true;
|
||||
}
|
||||
return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight));
|
||||
}
|
||||
|
||||
void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const {
|
||||
|
@ -520,15 +520,14 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info,
|
||||
case PICT_PICTURE_TAG: {
|
||||
fPictureCount = size;
|
||||
fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount);
|
||||
bool success;
|
||||
for (int i = 0; i < fPictureCount; i++) {
|
||||
fPictureRefs[i] = SkNEW_ARGS(SkPicture, (stream, &success, proc));
|
||||
// Success can only be false if PICTURE_VERSION does not match
|
||||
fPictureRefs[i] = SkPicture::CreateFromStream(stream, proc);
|
||||
// CreateFromStream can only fail if PICTURE_VERSION does not match
|
||||
// (which should never happen from here, since a sub picture will
|
||||
// have the same PICTURE_VERSION as its parent) or if stream->read
|
||||
// returns 0. In the latter case, we have a bug when writing the
|
||||
// picture to begin with, which will be alerted to here.
|
||||
SkASSERT(success);
|
||||
SkASSERT(fPictureRefs[i] != NULL);
|
||||
}
|
||||
} break;
|
||||
case PICT_BUFFER_SIZE_TAG: {
|
||||
|
@ -420,10 +420,9 @@ static void test_bitmap_with_encoded_data(skiatest::Reporter* reporter) {
|
||||
context.fReporter = reporter;
|
||||
SkSetErrorCallback(assert_one_parse_error_cb, &context);
|
||||
SkMemoryStream pictureStream(picture1);
|
||||
bool success;
|
||||
SkClearLastError();
|
||||
SkPicture pictureFromStream(&pictureStream, &success, NULL);
|
||||
REPORTER_ASSERT(reporter, success);
|
||||
SkAutoUnref pictureFromStream(SkPicture::CreateFromStream(&pictureStream, NULL));
|
||||
REPORTER_ASSERT(reporter, pictureFromStream.get() != NULL);
|
||||
SkClearLastError();
|
||||
SkSetErrorCallback(NULL, NULL);
|
||||
}
|
||||
|
@ -173,16 +173,15 @@ static bool run_single_benchmark(const SkString& inputPath,
|
||||
gLruImageCache.setImageCacheLimit(0);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
SkPicture* picture;
|
||||
SkPicture::InstallPixelRefProc proc;
|
||||
if (FLAGS_deferImageDecoding) {
|
||||
picture = SkNEW_ARGS(SkPicture, (&inputStream, &success, &lazy_decode_bitmap));
|
||||
proc = &lazy_decode_bitmap;
|
||||
} else {
|
||||
picture = SkNEW_ARGS(SkPicture, (&inputStream, &success, &SkImageDecoder::DecodeMemory));
|
||||
proc = &SkImageDecoder::DecodeMemory;
|
||||
}
|
||||
SkAutoTDelete<SkPicture> ad(picture);
|
||||
SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc));
|
||||
|
||||
if (!success) {
|
||||
if (NULL == picture.get()) {
|
||||
SkString err;
|
||||
err.printf("Could not read an SkPicture from %s\n", inputPath.c_str());
|
||||
gLogger.logError(err);
|
||||
|
@ -666,7 +666,7 @@ static int filter_picture(const SkString& inFile, const SkString& outFile) {
|
||||
|
||||
SkFILEStream inStream(inFile.c_str());
|
||||
if (inStream.isValid()) {
|
||||
inPicture.reset(SkNEW_ARGS(SkPicture, (&inStream, NULL, &SkImageDecoder::DecodeMemory)));
|
||||
inPicture.reset(SkPicture::CreateFromStream(&inStream));
|
||||
}
|
||||
|
||||
if (NULL == inPicture.get()) {
|
||||
|
@ -46,13 +46,7 @@ static SkPicture* load_picture(const char path[]) {
|
||||
SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
|
||||
SkPicture* pic = NULL;
|
||||
if (stream.get()) {
|
||||
bool success;
|
||||
pic = SkNEW_ARGS(SkPicture, (stream.get(), &success,
|
||||
&lazy_decode_bitmap));
|
||||
if (!success) {
|
||||
SkDELETE(pic);
|
||||
pic = NULL;
|
||||
}
|
||||
pic = SkPicture::CreateFromStream(stream.get(), &lazy_decode_bitmap);
|
||||
}
|
||||
return pic;
|
||||
}
|
||||
|
@ -40,11 +40,10 @@ static SkPicture* inspect(const char path[]) {
|
||||
}
|
||||
|
||||
stream.rewind();
|
||||
bool success = false;
|
||||
SkPicture* pic = SkNEW_ARGS(SkPicture, (&stream, &success, &lazy_decode_bitmap));
|
||||
if (!success) {
|
||||
SkPicture* pic = SkPicture::CreateFromStream(&stream, &lazy_decode_bitmap);
|
||||
if (NULL == pic) {
|
||||
SkDebugf("Could not create SkPicture: %s\n", path);
|
||||
return pic;
|
||||
return NULL;
|
||||
}
|
||||
printf("picture size:[%d %d]\n", pic->width(), pic->height());
|
||||
return pic;
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "SkDevice.h"
|
||||
#include "SkForceLinking.h"
|
||||
#include "SkGraphics.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "SkImageEncoder.h"
|
||||
#include "SkOSFile.h"
|
||||
#include "SkPicture.h"
|
||||
@ -169,11 +168,9 @@ static bool render_pdf(const SkString& inputPath, const SkString& outputDir,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
SkAutoTUnref<SkPicture>
|
||||
picture(SkNEW_ARGS(SkPicture, (&inputStream, &success, &SkImageDecoder::DecodeMemory)));
|
||||
SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream));
|
||||
|
||||
if (!success) {
|
||||
if (NULL == picture.get()) {
|
||||
SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -185,7 +182,7 @@ static bool render_pdf(const SkString& inputPath, const SkString& outputDir,
|
||||
|
||||
renderer.render();
|
||||
|
||||
success = write_output(outputDir, inputFilename, renderer);
|
||||
bool success = write_output(outputDir, inputFilename, renderer);
|
||||
|
||||
renderer.end();
|
||||
return success;
|
||||
|
@ -149,21 +149,22 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||
return false;
|
||||
}
|
||||
|
||||
SkDebugf("deserializing... %s\n", inputPath.c_str());
|
||||
|
||||
bool success = false;
|
||||
SkPicture* picture;
|
||||
SkPicture::InstallPixelRefProc proc;
|
||||
if (FLAGS_deferImageDecoding) {
|
||||
picture = SkNEW_ARGS(SkPicture, (&inputStream, &success, &lazy_decode_bitmap));
|
||||
proc = &lazy_decode_bitmap;
|
||||
} else if (FLAGS_writeEncodedImages) {
|
||||
SkASSERT(!FLAGS_writePath.isEmpty());
|
||||
reset_image_file_base_name(inputFilename);
|
||||
picture = SkNEW_ARGS(SkPicture, (&inputStream, &success, &write_image_to_file));
|
||||
proc = &write_image_to_file;
|
||||
} else {
|
||||
picture = SkNEW_ARGS(SkPicture, (&inputStream, &success, &SkImageDecoder::DecodeMemory));
|
||||
proc = &SkImageDecoder::DecodeMemory;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
SkDebugf("deserializing... %s\n", inputPath.c_str());
|
||||
|
||||
SkPicture* picture = SkPicture::CreateFromStream(&inputStream, proc);
|
||||
|
||||
if (NULL == picture) {
|
||||
SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str());
|
||||
return false;
|
||||
}
|
||||
@ -186,7 +187,7 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir,
|
||||
make_output_filepath(outputPath, *outputDir, inputFilename);
|
||||
}
|
||||
|
||||
success = renderer.render(outputPath, out);
|
||||
bool success = renderer.render(outputPath, out);
|
||||
if (outputPath) {
|
||||
if (!success) {
|
||||
SkDebugf("Could not write to file %s\n", outputPath->c_str());
|
||||
|
Loading…
Reference in New Issue
Block a user