Update comment in header to make it more clear that the picture
should be unaltered after creating the shader. We want our shaders
to be immutable, and this supports that.
Make the factory return NULL if the shader would have never drawn
anyway i.e. for a null picture or picture with no width/height.
Addresses comments I brought up in
https://codereview.chromium.org/
221923007/#msg16.
BUG=skia:1976
R=reed@google.com, fmalita@chromium.org, robertphillips@google.com
Author: scroggo@google.com
Review URL: https://codereview.chromium.org/
238253005
git-svn-id: http://skia.googlecode.com/svn/trunk@14288
2bbb7eff-a529-9590-31e7-
b0007b416f81
'../tests/PathTest.cpp',
'../tests/PathUtilsTest.cpp',
'../tests/PictureTest.cpp',
+ '../tests/PictureShaderTest.cpp',
'../tests/PictureUtilsTest.cpp',
'../tests/PixelRefTest.cpp',
'../tests/PointTest.cpp',
/** Call this to create a new shader that will draw with the specified picture.
*
* @param src The picture to use inside the shader (if not NULL, its ref count
- * is incremented).
+ * is incremented). The SkPicture must not be changed after
+ * successfully creating a picture shader.
+ * FIXME: src cannot be const due to SkCanvas::drawPicture
* @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
* @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
* @return Returns a new shader object. Note: this function never returns null.
#endif
SkPictureShader::SkPictureShader(SkPicture* picture, TileMode tmx, TileMode tmy)
- : fPicture(picture)
+ : fPicture(SkRef(picture))
, fTmx(tmx)
- , fTmy(tmy) {
- SkSafeRef(fPicture);
-}
+ , fTmy(tmy) { }
SkPictureShader::SkPictureShader(SkReadBuffer& buffer)
: INHERITED(buffer) {
fTmx = static_cast<SkShader::TileMode>(buffer.read32());
fTmy = static_cast<SkShader::TileMode>(buffer.read32());
- if (buffer.readBool()) {
- fPicture = SkPicture::CreateFromBuffer(buffer);
- } else {
- fPicture = NULL;
- }
+ fPicture = SkPicture::CreateFromBuffer(buffer);
}
SkPictureShader::~SkPictureShader() {
- SkSafeUnref(fPicture);
+ fPicture->unref();
}
SkPictureShader* SkPictureShader::Create(SkPicture* picture, TileMode tmx, TileMode tmy) {
+ if (!picture || 0 == picture->width() || 0 == picture->height()) {
+ return NULL;
+ }
return SkNEW_ARGS(SkPictureShader, (picture, tmx, tmy));
}
buffer.write32(fTmx);
buffer.write32(fTmy);
- buffer.writeBool(NULL != fPicture);
- if (fPicture) {
- fPicture->flatten(buffer);
- }
+ fPicture->flatten(buffer);
}
bool SkPictureShader::buildBitmapShader(const SkMatrix& matrix) const {
- if (!fPicture || (0 == fPicture->width() && 0 == fPicture->height())) {
- return false;
- }
+ SkASSERT(fPicture && fPicture->width() > 0 && fPicture->height() > 0);
SkMatrix m;
if (this->hasLocalMatrix()) {
--- /dev/null
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkPicture.h"
+#include "SkPictureRecorder.h"
+#include "SkShader.h"
+#include "Test.h"
+
+// Test that attempting to create a picture shader with a NULL picture or
+// empty picture returns NULL.
+DEF_TEST(PictureShader_empty, reporter) {
+ SkShader* shader = SkShader::CreatePictureShader(NULL,
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+ REPORTER_ASSERT(reporter, NULL == shader);
+
+ SkPictureRecorder factory;
+ factory.beginRecording(0, 0, NULL, 0);
+ SkAutoTUnref<SkPicture> picture(factory.endRecording());
+ shader = SkShader::CreatePictureShader(picture.get(),
+ SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
+ REPORTER_ASSERT(reporter, NULL == shader);
+}