From 8afcb0fe2daa95d03d7757b1e3702d59a2b151a7 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Thu, 4 Jun 2015 13:51:44 -0400 Subject: [PATCH] Canvas.concat takes a 16-element Float32List instead of an array. The array should be in column-major format, in the format used by vector_math.dart. R=abarth@chromium.org Review URL: https://codereview.chromium.org/1155193004 --- engine/bindings/scripts/dart_types.py | 2 ++ engine/core/painting/Canvas.cpp | 19 +++++++++-- engine/core/painting/Canvas.h | 3 +- engine/core/painting/Canvas.idl | 2 +- engine/tonic/BUILD.gn | 2 ++ engine/tonic/float32_list.cc | 47 +++++++++++++++++++++++++++ engine/tonic/float32_list.h | 44 +++++++++++++++++++++++++ examples/raw/painting.sky | 12 ++++--- 8 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 engine/tonic/float32_list.cc create mode 100644 engine/tonic/float32_list.h diff --git a/engine/bindings/scripts/dart_types.py b/engine/bindings/scripts/dart_types.py index dde7436e611..d1f07db17ff 100644 --- a/engine/bindings/scripts/dart_types.py +++ b/engine/bindings/scripts/dart_types.py @@ -116,6 +116,7 @@ CPP_SPECIAL_CONVERSION_RULES = { 'unrestricted float': 'float', # Pass these by value, not pointer. 'Color': 'SkColor', + 'Float32List': 'Float32List', 'Point': 'Point', 'Rect': 'Rect', 'TransferMode': 'SkXfermode::Mode', @@ -363,6 +364,7 @@ DART_TO_CPP_VALUE = { # Pass-by-value types. 'Color': pass_by_value_format('CanvasColor'), + 'Float32List': pass_by_value_format('Float32List'), 'Point': pass_by_value_format('{implemented_as}'), 'Rect': pass_by_value_format('{implemented_as}'), 'TransferMode': pass_by_value_format('TransferMode'), diff --git a/engine/core/painting/Canvas.cpp b/engine/core/painting/Canvas.cpp index 1fa585569f7..ccd4fafaaab 100644 --- a/engine/core/painting/Canvas.cpp +++ b/engine/core/painting/Canvas.cpp @@ -83,14 +83,27 @@ void Canvas::skew(float sx, float sy) m_canvas->skew(sx, sy); } -void Canvas::concat(const Vector& matrix) +void Canvas::concat(const Float32List& matrix4) { if (!m_canvas) return; ASSERT(m_displayList->isRecording()); - ASSERT(matrix.size() == 9); + ASSERT(matrix4.data()); + + // TODO(mpcomplete): how can we raise an error in this case? + if (matrix4.num_elements() != 16) + return; + SkMatrix sk_matrix; - sk_matrix.set9(matrix.data()); + // Mappings from SkMatrix-index to input-index. + static const int kMappings[] = { + 0, 4, 12, + 1, 5, 13, + 3, 7, 15, + }; + for (intptr_t i = 0; i < 9; ++i) + sk_matrix[i] = matrix4.data()[kMappings[i]]; + m_canvas->concat(sk_matrix); } diff --git a/engine/core/painting/Canvas.h b/engine/core/painting/Canvas.h index ad5691b79ec..7571242dc2f 100644 --- a/engine/core/painting/Canvas.h +++ b/engine/core/painting/Canvas.h @@ -11,6 +11,7 @@ #include "sky/engine/core/painting/Rect.h" #include "sky/engine/platform/graphics/DisplayList.h" #include "sky/engine/tonic/dart_wrappable.h" +#include "sky/engine/tonic/float32_list.h" #include "sky/engine/wtf/PassRefPtr.h" #include "sky/engine/wtf/RefCounted.h" @@ -37,7 +38,7 @@ public: void scale(float sx, float sy); void rotateDegrees(float degrees); void skew(float sx, float sy); - void concat(const Vector& matrix); + void concat(const Float32List& matrix4); void clipRect(const Rect& rect); diff --git a/engine/core/painting/Canvas.idl b/engine/core/painting/Canvas.idl index 074bdff9683..ae833fcd321 100644 --- a/engine/core/painting/Canvas.idl +++ b/engine/core/painting/Canvas.idl @@ -17,7 +17,7 @@ interface Canvas { void scale(float sx, float sy); void rotateDegrees(float degrees); void skew(float sx, float sy); - void concat(float[] matrix9); + void concat(Float32List matrix4); void clipRect(Rect rect); diff --git a/engine/tonic/BUILD.gn b/engine/tonic/BUILD.gn index 673dfc6ef56..3baaf41ddf0 100644 --- a/engine/tonic/BUILD.gn +++ b/engine/tonic/BUILD.gn @@ -42,6 +42,8 @@ source_set("tonic") { "dart_wrappable.cc", "dart_wrappable.h", "dart_wrapper_info.h", + "float32_list.cc", + "float32_list.h", "mojo_converter.h", ] diff --git a/engine/tonic/float32_list.cc b/engine/tonic/float32_list.cc new file mode 100644 index 00000000000..56d59b87f4c --- /dev/null +++ b/engine/tonic/float32_list.cc @@ -0,0 +1,47 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "sky/engine/config.h" +#include "sky/engine/tonic/dart_error.h" +#include "sky/engine/tonic/float32_list.h" + +namespace blink { + +Float32List::Float32List(Dart_Handle list) + : data_(nullptr), num_elements_(0), dart_handle_(list) { + if (Dart_IsNull(list)) + return; + + Dart_TypedData_Type type; + Dart_TypedDataAcquireData( + list, &type, reinterpret_cast(&data_), &num_elements_); + DCHECK(!LogIfError(list)); + ASSERT(type == Dart_TypedData_kFloat32); +} + +Float32List::Float32List(Float32List&& other) + : data_(other.data_), + num_elements_(other.num_elements_), + dart_handle_(other.dart_handle_) { + other.data_ = nullptr; + other.dart_handle_ = nullptr; +} + +Float32List::~Float32List() { + if (data_) + Dart_TypedDataReleaseData(dart_handle_); +} + +Float32List DartConverter::FromArgumentsWithNullCheck( + Dart_NativeArguments args, + int index, + Dart_Handle& exception) { + Dart_Handle list = Dart_GetNativeArgument(args, index); + DCHECK(!LogIfError(list)); + + Float32List result(list); + return result; +} + +} // namespace blink diff --git a/engine/tonic/float32_list.h b/engine/tonic/float32_list.h new file mode 100644 index 00000000000..be9503ba315 --- /dev/null +++ b/engine/tonic/float32_list.h @@ -0,0 +1,44 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SKY_ENGINE_TONIC_FLOAT32_LIST_H_ +#define SKY_ENGINE_TONIC_FLOAT32_LIST_H_ + +#include "dart/runtime/include/dart_api.h" +#include "sky/engine/tonic/dart_converter.h" + +namespace blink { + +// A simple wrapper around a Dart Float32List. It uses Dart_TypedDataAcquireData +// to obtain a raw pointer to the data, which is released when this object is +// destroyed. +// +// This is designed to be used with DartConverter only. +class Float32List { + public: + explicit Float32List(Dart_Handle list); + Float32List(Float32List&& other); + ~Float32List(); + + const float* data() const { return data_; } + intptr_t num_elements() const { return num_elements_; } + + private: + float* data_; + intptr_t num_elements_; + Dart_Handle dart_handle_; + + Float32List(const Float32List& other) = delete; +}; + +template <> +struct DartConverter { + static Float32List FromArgumentsWithNullCheck(Dart_NativeArguments args, + int index, + Dart_Handle& exception); +}; + +} // namespace blink + +#endif // SKY_ENGINE_TONIC_FLOAT32_LIST_H_ diff --git a/examples/raw/painting.sky b/examples/raw/painting.sky index 70c519febe8..075867a8c6e 100644 --- a/examples/raw/painting.sky +++ b/examples/raw/painting.sky @@ -8,6 +8,7 @@ div {