Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h |
| diff --git a/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h b/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h |
| index 3c3781bc87a3a63ba77324fec711ceb68d8e1fdb..9cb06f92a26ad9f942dcad7a3fe4efe85b11fb1f 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h |
| +++ b/third_party/WebKit/Source/platform/graphics/skia/SkiaUtils.h |
| @@ -38,6 +38,7 @@ |
| #include "platform/graphics/Image.h" |
| #include "platform/transforms/AffineTransform.h" |
| #include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkRefCnt.h" |
| #include "wtf/MathExtras.h" |
| namespace blink { |
| @@ -126,6 +127,85 @@ inline SkCanvas::SrcRectConstraint WebCoreClampingModeToSkiaRectConstraint(Image |
| : SkCanvas::kFast_SrcRectConstraint; |
| } |
| + |
| +// Skia's smart pointer APIs are preferable over their legacy raw pointer counterparts. |
| +// The following helpers ensure interoperability between Skia's SkRefCnt wrapper sk_sp<T> and |
| +// Blink's RefPtr<T>/PassRefPtr<T>. |
| +// |
| +// - adoptRef(sk_sp<T>&&): adopts an sk_sp rvalue into a PassRefPtr (to be used when |
| +// transferring ownership from Skia to Blink). |
| +// - adoptSkSp(PassRefPtr<T>&&): adopts a PassRefPtr rvalue into a sk_sp (to be used when |
| +// transferring ownership from Blink to Skia). |
| +// |
| +// General guidelines |
| +// |
| +// When receiving ref counted objects from Skia: |
| +// |
| +// 1) use sk_sp-based Skia factories if available (e.g. SkShader::MakeFoo() instead of |
| +// SkShader::CreateFoo()) |
| +// |
| +// 2) use sk_sp<T> locals for temporary objects (to be immediately transferred back to Skia) |
| +// |
| +// 3) use RefPtr<T>/PassRefPtr<T> for objects to be retained in Blink, use |
| +// adoptRef(sk_sp<T>&&) to convert |
| +// |
| +// When passing ref counted objects to Skia: |
| +// |
| +// 1) use sk_sk-based Skia APIs when available (e.g. SkPaint::setShader(sk_sp<SkShader>) |
| +// instead of SkPaint::setShader(SkShader*)) |
| +// |
| +// 2) if the object ownership is being passed to Skia, use std::move(sk_sp<T>) or |
| +// adoptSkSp(PassRefPtr<T>&&) to transfer without refcount churn |
| +// |
| +// 3) if the object ownership is shared with Skia (Blink retains a reference), use |
| +// sk_ref_sp(RefPtr<T>::get()) |
| +// |
| +// Example (creating a SkShader and setting it on SkPaint): |
| +// |
| +// a) legacy/old style |
| +// |
| +// RefPtr<SkShader> shader = adoptRef(SkShader::CreateFoo(...)); |
| +// paint.setShader(shader.get()); |
| +// |
| +// (Note: the legacy approach introduces refcount churn as Skia grabs a ref while Blink is |
| +// temporarily holding on to its own) |
| +// |
| +// b) new style, ownership transferred |
| +// |
| +// // using Skia smart pointer locals |
| +// sk_sp<SkShader> shader = SkShader::MakeFoo(...); |
| +// paint.setShader(std::move(shader)); |
| +// |
| +// // using Blink smart pointer locals |
| +// RefPtr<SkShader> shader = adoptRef(SkShader::MakeFoo(...)); |
| +// paint.setShader(adoptSkSp(shader.release()); |
| +// |
| +// // using no locals |
| +// paint.setShader(SkShader::MakeFoo(...)); |
| +// |
| +// (Note: while all these variants avoid ref count churn, the last/inlined-factory version |
| +// is preferred when feasible because it also skips the adopt/move op) |
|
jbroman
2016/03/16 14:43:08
Why? The adopt/move will presumably be elided by t
f(malita)
2016/03/16 16:51:45
Experimentally, the first example above does not e
|
| +// |
| +// c) new style, shared ownership |
| +// |
| +// // using sk_ref_sp |
| +// RefPtr<SkShader> m_shader = adoptRef(SkShader::MakeFoo(...)); |
| +// paint.setShader(sk_ref_sp(m_shader.get())); |
| +// |
| +// // using a temp PassRefPtr and sk_sp adoption |
| +// RefPtr<SkShader> m_shader = adoptRef(SkShader::MakeFoo(...)); |
| +// paint.setShader(adoptSkSp(PassRefPtr<SkShader>(m_shader))); |
| +// |
| +template <typename T> PassRefPtr<T> adoptRef(sk_sp<T>&& sp) |
|
jbroman
2016/03/16 14:43:08
I also think taking the sk_sp by value is probably
f(malita)
2016/03/16 16:51:45
We've had a little discussion regarding val vs. rv
danakj
2016/03/16 17:54:53
(google style guide also says not to do write && e
|
| +{ |
| + return adoptRef(sp.release()); |
| +} |
| + |
| +template <typename T> sk_sp<T> adoptSkSp(PassRefPtr<T>&& ref) |
|
jbroman
2016/03/16 14:43:08
To be consistent with other usage of PassRefPtr, I
f(malita)
2016/03/16 16:51:45
Makes sense, done.
|
| +{ |
| + return sk_sp<T>(ref.leakRef()); |
| +} |
| + |
| } // namespace blink |
| #endif // SkiaUtils_h |