| // Copyright 2013 The Flutter 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 "flutter/lib/ui/painting/vertices.h" |
| |
| #include <algorithm> |
| |
| #include "flutter/lib/ui/ui_dart_state.h" |
| #include "third_party/tonic/dart_binding_macros.h" |
| #include "third_party/tonic/dart_library_natives.h" |
| |
| namespace flutter { |
| |
| namespace { |
| |
| void DecodePoints(const tonic::Float32List& coords, SkPoint* points) { |
| for (int i = 0; i < coords.num_elements(); i += 2) { |
| points[i / 2] = SkPoint::Make(coords[i], coords[i + 1]); |
| } |
| } |
| |
| template <typename T> |
| void DecodeInts(const tonic::Int32List& ints, T* out) { |
| for (int i = 0; i < ints.num_elements(); i++) { |
| out[i] = ints[i]; |
| } |
| } |
| |
| } // namespace |
| |
| IMPLEMENT_WRAPPERTYPEINFO(ui, Vertices); |
| |
| #define FOR_EACH_BINDING(V) V(Vertices, init) |
| |
| FOR_EACH_BINDING(DART_NATIVE_CALLBACK) |
| |
| Vertices::Vertices() {} |
| |
| Vertices::~Vertices() {} |
| |
| void Vertices::RegisterNatives(tonic::DartLibraryNatives* natives) { |
| natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); |
| } |
| |
| bool Vertices::init(Dart_Handle vertices_handle, |
| SkVertices::VertexMode vertex_mode, |
| const tonic::Float32List& positions, |
| const tonic::Float32List& texture_coordinates, |
| const tonic::Int32List& colors, |
| const tonic::Uint16List& indices) { |
| UIDartState::ThrowIfUIOperationsProhibited(); |
| uint32_t builderFlags = 0; |
| if (texture_coordinates.data()) { |
| builderFlags |= SkVertices::kHasTexCoords_BuilderFlag; |
| } |
| if (colors.data()) { |
| builderFlags |= SkVertices::kHasColors_BuilderFlag; |
| } |
| |
| SkVertices::Builder builder(vertex_mode, positions.num_elements() / 2, |
| indices.num_elements(), builderFlags); |
| |
| if (!builder.isValid()) { |
| return false; |
| } |
| |
| // positions are required for SkVertices::Builder |
| FML_DCHECK(positions.data()); |
| if (positions.data()) { |
| DecodePoints(positions, builder.positions()); |
| } |
| |
| if (texture_coordinates.data()) { |
| // SkVertices::Builder assumes equal numbers of elements |
| FML_DCHECK(positions.num_elements() == texture_coordinates.num_elements()); |
| DecodePoints(texture_coordinates, builder.texCoords()); |
| } |
| if (colors.data()) { |
| // SkVertices::Builder assumes equal numbers of elements |
| FML_DCHECK(positions.num_elements() / 2 == colors.num_elements()); |
| DecodeInts<SkColor>(colors, builder.colors()); |
| } |
| |
| if (indices.data()) { |
| std::copy(indices.data(), indices.data() + indices.num_elements(), |
| builder.indices()); |
| } |
| |
| auto vertices = fml::MakeRefCounted<Vertices>(); |
| vertices->vertices_ = builder.detach(); |
| vertices->AssociateWithDartWrapper(vertices_handle); |
| |
| return true; |
| } |
| |
| size_t Vertices::GetAllocationSize() const { |
| return sizeof(Vertices) + vertices_->approximateSize(); |
| } |
| |
| } // namespace flutter |