|
34 | 34 | namespace impeller {
|
35 | 35 | namespace testing {
|
36 | 36 |
|
| 37 | +flutter::DlColor toColor(const float* components) { |
| 38 | + auto value = (((std::lround(components[3] * 255) & 0xff) << 24) | |
| 39 | + ((std::lround(components[0] * 255) & 0xff) << 16) | |
| 40 | + ((std::lround(components[1] * 255) & 0xff) << 8) | |
| 41 | + ((std::lround(components[2] * 255) & 0xff) << 0)) & |
| 42 | + 0xFFFFFFFF; |
| 43 | + return flutter::DlColor(value); |
| 44 | +} |
| 45 | + |
37 | 46 | using DisplayListTest = DisplayListPlayground;
|
38 | 47 | INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest);
|
39 | 48 |
|
@@ -1159,6 +1168,97 @@ TEST_P(DisplayListTest, DrawShapes) {
|
1159 | 1168 | ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
|
1160 | 1169 | }
|
1161 | 1170 |
|
| 1171 | +TEST_P(DisplayListTest, DrawVerticesBlendModes) { |
| 1172 | + std::vector<const char*> blend_mode_names; |
| 1173 | + std::vector<flutter::DlBlendMode> blend_mode_values; |
| 1174 | + { |
| 1175 | + const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = { |
| 1176 | + // Pipeline blends (Porter-Duff alpha compositing) |
| 1177 | + {"Clear", flutter::DlBlendMode::kClear}, |
| 1178 | + {"Source", flutter::DlBlendMode::kSrc}, |
| 1179 | + {"Destination", flutter::DlBlendMode::kDst}, |
| 1180 | + {"SourceOver", flutter::DlBlendMode::kSrcOver}, |
| 1181 | + {"DestinationOver", flutter::DlBlendMode::kDstOver}, |
| 1182 | + {"SourceIn", flutter::DlBlendMode::kSrcIn}, |
| 1183 | + {"DestinationIn", flutter::DlBlendMode::kDstIn}, |
| 1184 | + {"SourceOut", flutter::DlBlendMode::kSrcOut}, |
| 1185 | + {"DestinationOut", flutter::DlBlendMode::kDstOut}, |
| 1186 | + {"SourceATop", flutter::DlBlendMode::kSrcATop}, |
| 1187 | + {"DestinationATop", flutter::DlBlendMode::kDstATop}, |
| 1188 | + {"Xor", flutter::DlBlendMode::kXor}, |
| 1189 | + {"Plus", flutter::DlBlendMode::kPlus}, |
| 1190 | + {"Modulate", flutter::DlBlendMode::kModulate}, |
| 1191 | + // Advanced blends (color component blends) |
| 1192 | + {"Screen", flutter::DlBlendMode::kScreen}, |
| 1193 | + {"Overlay", flutter::DlBlendMode::kOverlay}, |
| 1194 | + {"Darken", flutter::DlBlendMode::kDarken}, |
| 1195 | + {"Lighten", flutter::DlBlendMode::kLighten}, |
| 1196 | + {"ColorDodge", flutter::DlBlendMode::kColorDodge}, |
| 1197 | + {"ColorBurn", flutter::DlBlendMode::kColorBurn}, |
| 1198 | + {"HardLight", flutter::DlBlendMode::kHardLight}, |
| 1199 | + {"SoftLight", flutter::DlBlendMode::kSoftLight}, |
| 1200 | + {"Difference", flutter::DlBlendMode::kDifference}, |
| 1201 | + {"Exclusion", flutter::DlBlendMode::kExclusion}, |
| 1202 | + {"Multiply", flutter::DlBlendMode::kMultiply}, |
| 1203 | + {"Hue", flutter::DlBlendMode::kHue}, |
| 1204 | + {"Saturation", flutter::DlBlendMode::kSaturation}, |
| 1205 | + {"Color", flutter::DlBlendMode::kColor}, |
| 1206 | + {"Luminosity", flutter::DlBlendMode::kLuminosity}, |
| 1207 | + }; |
| 1208 | + assert(blends.size() == |
| 1209 | + static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1); |
| 1210 | + for (const auto& [name, mode] : blends) { |
| 1211 | + blend_mode_names.push_back(name); |
| 1212 | + blend_mode_values.push_back(mode); |
| 1213 | + } |
| 1214 | + } |
| 1215 | + |
| 1216 | + auto callback = [&]() { |
| 1217 | + static int current_blend_index = 3; |
| 1218 | + static float dst_alpha = 1; |
| 1219 | + static float src_alpha = 1; |
| 1220 | + static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f}; |
| 1221 | + static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f}; |
| 1222 | + static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f}; |
| 1223 | + static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| 1224 | + |
| 1225 | + ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); |
| 1226 | + { |
| 1227 | + ImGui::ListBox("Blending mode", ¤t_blend_index, |
| 1228 | + blend_mode_names.data(), blend_mode_names.size()); |
| 1229 | + ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1); |
| 1230 | + ImGui::ColorEdit4("Color A", color0); |
| 1231 | + ImGui::ColorEdit4("Color B", color1); |
| 1232 | + ImGui::ColorEdit4("Color C", color2); |
| 1233 | + ImGui::ColorEdit4("Source Color", src_color); |
| 1234 | + ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1); |
| 1235 | + } |
| 1236 | + ImGui::End(); |
| 1237 | + |
| 1238 | + std::vector<SkPoint> positions = {SkPoint::Make(100, 300), |
| 1239 | + SkPoint::Make(200, 100), |
| 1240 | + SkPoint::Make(300, 300)}; |
| 1241 | + std::vector<flutter::DlColor> colors = { |
| 1242 | + toColor(color0).modulateOpacity(dst_alpha), |
| 1243 | + toColor(color1).modulateOpacity(dst_alpha), |
| 1244 | + toColor(color2).modulateOpacity(dst_alpha)}; |
| 1245 | + |
| 1246 | + auto vertices = flutter::DlVertices::Make( |
| 1247 | + flutter::DlVertexMode::kTriangles, 3, positions.data(), |
| 1248 | + /*texture_coorindates=*/nullptr, colors.data()); |
| 1249 | + |
| 1250 | + flutter::DisplayListBuilder builder; |
| 1251 | + flutter::DlPaint paint; |
| 1252 | + |
| 1253 | + paint.setColor(toColor(src_color).modulateOpacity(src_alpha)); |
| 1254 | + builder.drawVertices(vertices, blend_mode_values[current_blend_index], |
| 1255 | + paint); |
| 1256 | + return builder.Build(); |
| 1257 | + }; |
| 1258 | + |
| 1259 | + ASSERT_TRUE(OpenPlaygroundHere(callback)); |
| 1260 | +} |
| 1261 | + |
1162 | 1262 | #ifdef IMPELLER_ENABLE_3D
|
1163 | 1263 | TEST_P(DisplayListTest, SceneColorSource) {
|
1164 | 1264 | // Load up the scene.
|
|
0 commit comments