1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/lib/ui/painting/vertices.h"
6#include "flutter/lib/ui/ui_dart_state.h"
7
8#include <algorithm>
9
10#include "third_party/tonic/dart_binding_macros.h"
11#include "third_party/tonic/dart_library_natives.h"
12
13namespace flutter {
14
15namespace {
16
17void DecodePoints(const tonic::Float32List& coords, SkPoint* points) {
18 for (int i = 0; i < coords.num_elements(); i += 2) {
19 points[i / 2] = SkPoint::Make(coords[i], coords[i + 1]);
20 }
21}
22
23template <typename T>
24void DecodeInts(const tonic::Int32List& ints, T* out) {
25 for (int i = 0; i < ints.num_elements(); i++) {
26 out[i] = ints[i];
27 }
28}
29
30} // namespace
31
32IMPLEMENT_WRAPPERTYPEINFO(ui, Vertices);
33
34#define FOR_EACH_BINDING(V) V(Vertices, init)
35
36FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
37
38Vertices::Vertices() {}
39
40Vertices::~Vertices() {}
41
42void Vertices::RegisterNatives(tonic::DartLibraryNatives* natives) {
43 natives->Register({FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
44}
45
46bool Vertices::init(Dart_Handle vertices_handle,
47 SkVertices::VertexMode vertex_mode,
48 const tonic::Float32List& positions,
49 const tonic::Float32List& texture_coordinates,
50 const tonic::Int32List& colors,
51 const tonic::Uint16List& indices) {
52 UIDartState::ThrowIfUIOperationsProhibited();
53 uint32_t builderFlags = 0;
54 if (texture_coordinates.data()) {
55 builderFlags |= SkVertices::kHasTexCoords_BuilderFlag;
56 }
57 if (colors.data()) {
58 builderFlags |= SkVertices::kHasColors_BuilderFlag;
59 }
60
61 SkVertices::Builder builder(vertex_mode, positions.num_elements() / 2,
62 indices.num_elements(), builderFlags);
63
64 if (!builder.isValid()) {
65 return false;
66 }
67
68 // positions are required for SkVertices::Builder
69 FML_DCHECK(positions.data());
70 if (positions.data()) {
71 DecodePoints(positions, builder.positions());
72 }
73
74 if (texture_coordinates.data()) {
75 // SkVertices::Builder assumes equal numbers of elements
76 FML_DCHECK(positions.num_elements() == texture_coordinates.num_elements());
77 DecodePoints(texture_coordinates, builder.texCoords());
78 }
79 if (colors.data()) {
80 // SkVertices::Builder assumes equal numbers of elements
81 FML_DCHECK(positions.num_elements() / 2 == colors.num_elements());
82 DecodeInts<SkColor>(colors, builder.colors());
83 }
84
85 if (indices.data()) {
86 std::copy(indices.data(), indices.data() + indices.num_elements(),
87 builder.indices());
88 }
89
90 auto vertices = fml::MakeRefCounted<Vertices>();
91 vertices->vertices_ = builder.detach();
92 vertices->AssociateWithDartWrapper(vertices_handle);
93
94 return true;
95}
96
97size_t Vertices::GetAllocationSize() const {
98 return sizeof(Vertices) + vertices_->approximateSize();
99}
100
101} // namespace flutter
102