diff --git a/DEPS b/DEPS index 4042ebeef53d6..9c47002732a2a 100644 --- a/DEPS +++ b/DEPS @@ -23,7 +23,7 @@ vars = { 'fuchsia_git': 'https://fuchsia.googlesource.com', 'github_git': 'https://github.com', 'skia_git': 'https://skia.googlesource.com', - 'skia_revision': '24e58341fbcd904fdf81d86e5a7703e254d63e35', + 'skia_revision': '71f8475a0dbacc5d63fef094100835bad7b1e74c', # When updating the Dart revision, ensure that all entries that are # dependencies of Dart are also updated to match the entries in the @@ -31,7 +31,7 @@ vars = { # Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS. # You can use //tools/dart/create_updated_flutter_deps.py to produce # updated revision list of existing dependencies. - 'dart_revision': '760a9690c22ec3f3d163173737f9949f97e6e02a', + 'dart_revision': '2b995b2654ba162c48cdd187ce0b2f1d24c6838f', 'dart_args_tag': '1.4.4', 'dart_async_tag': '2.0.8', @@ -115,7 +115,7 @@ allowed_hosts = [ ] deps = { - 'src': 'https://github.com/flutter/buildroot.git' + '@' + '35959f6255c341eee550884ed69afd6b2891bd53', + 'src': 'https://github.com/flutter/buildroot.git' + '@' + '7aadfaf196f9cd8a299f9ad78fab63362800466d', # Fuchsia compatibility # @@ -124,7 +124,7 @@ deps = { # and not have to specific specific hashes. 'src/third_party/tonic': - Var('fuchsia_git') + '/tonic' + '@' + '90c9c81f49461d9f4d414845a6eeba1c0df35bb4', + Var('fuchsia_git') + '/tonic' + '@' + 'd91fa62844f8531a3701450f6192298d0e873246', 'src/third_party/benchmark': Var('fuchsia_git') + '/third_party/benchmark' + '@' + '296537bc48d380adf21567c5d736ab79f5363d22', diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 813bdff51f800..62c4bcd7b2671 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -819,8 +819,6 @@ FILE: ../../../flutter/shell/common/animator.cc FILE: ../../../flutter/shell/common/animator.h FILE: ../../../flutter/shell/common/engine.cc FILE: ../../../flutter/shell/common/engine.h -FILE: ../../../flutter/shell/common/picture_serializer.cc -FILE: ../../../flutter/shell/common/picture_serializer.h FILE: ../../../flutter/shell/common/platform_view.cc FILE: ../../../flutter/shell/common/platform_view.h FILE: ../../../flutter/shell/common/rasterizer.cc diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 9b6281e840565..31cb5f4ce3bbe 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: af91da401385350e1fd99d6d8f3947a4 +Signature: 2d0f3b3ff2a5279313bfee7ef0cef7c5 UNUSED LICENSES: @@ -959,8 +959,6 @@ FILE: ../../../third_party/skia/src/core/SkColorSpace.cpp FILE: ../../../third_party/skia/src/core/SkColorSpacePriv.h FILE: ../../../third_party/skia/src/core/SkColorSpaceXform.cpp FILE: ../../../third_party/skia/src/core/SkColorSpaceXformPriv.h -FILE: ../../../third_party/skia/src/core/SkColorSpace_XYZ.cpp -FILE: ../../../third_party/skia/src/core/SkColorSpace_XYZ.h FILE: ../../../third_party/skia/src/core/SkCpu.cpp FILE: ../../../third_party/skia/src/core/SkCpu.h FILE: ../../../third_party/skia/src/core/SkDeduper.h @@ -1495,9 +1493,6 @@ FILE: ../../../third_party/skia/src/gpu/effects/GrLumaColorFilterEffect.h FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.fp FILE: ../../../third_party/skia/src/gpu/effects/GrMagnifierEffect.h -FILE: ../../../third_party/skia/src/gpu/effects/GrOverdrawFragmentProcessor.cpp -FILE: ../../../third_party/skia/src/gpu/effects/GrOverdrawFragmentProcessor.fp -FILE: ../../../third_party/skia/src/gpu/effects/GrOverdrawFragmentProcessor.h FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.cpp FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.fp FILE: ../../../third_party/skia/src/gpu/effects/GrPremulInputFragmentProcessor.h diff --git a/ci/licenses_golden/licenses_third_party b/ci/licenses_golden/licenses_third_party index 2d0cf91811ccd..aca13aa04fe96 100644 --- a/ci/licenses_golden/licenses_third_party +++ b/ci/licenses_golden/licenses_third_party @@ -1,4 +1,4 @@ -Signature: 149340ef002a59fe0840631d6cfd1773 +Signature: 5ff2cabdf3ef0c70254ec22bc9e767c6 UNUSED LICENSES: @@ -5461,6 +5461,7 @@ FILE: ../../../third_party/dart/runtime/vm/compiler/backend/code_statistics.cc FILE: ../../../third_party/dart/runtime/vm/compiler/backend/code_statistics.h FILE: ../../../third_party/dart/runtime/vm/compiler/compiler_pass.cc FILE: ../../../third_party/dart/runtime/vm/compiler/compiler_pass.h +FILE: ../../../third_party/dart/runtime/vm/compiler/compiler_state.h FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/base_flow_graph_builder.cc FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/base_flow_graph_builder.h FILE: ../../../third_party/dart/runtime/vm/compiler/frontend/bytecode_reader.cc diff --git a/flow/matrix_decomposition.cc b/flow/matrix_decomposition.cc index 73a774b4dd037..0cc035cbba216 100644 --- a/flow/matrix_decomposition.cc +++ b/flow/matrix_decomposition.cc @@ -28,6 +28,15 @@ static inline SkVector3 SkVector3Cross(const SkVector3& a, const SkVector3& b) { MatrixDecomposition::MatrixDecomposition(const SkMatrix& matrix) : MatrixDecomposition(SkMatrix44{matrix}) {} +// Use custom normalize to avoid skia precision loss/normalize() privatization. +static inline void SkVector3Normalize(SkVector3& v) { + double mag = sqrt(v.fX * v.fX + v.fY * v.fY + v.fZ * v.fZ); + double scale = 1.0 / mag; + v.fX *= scale; + v.fY *= scale; + v.fZ *= scale; +} + MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) { if (matrix.get(3, 3) == 0) { return; @@ -83,14 +92,14 @@ MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) { scale_.fX = row[0].length(); - row[0].normalize(); + SkVector3Normalize(row[0]); shear_.fX = row[0].dot(row[1]); row[1] = SkVector3Combine(row[1], 1.0, row[0], -shear_.fX); scale_.fY = row[1].length(); - row[1].normalize(); + SkVector3Normalize(row[1]); shear_.fX /= scale_.fY; @@ -101,7 +110,7 @@ MatrixDecomposition::MatrixDecomposition(SkMatrix44 matrix) : valid_(false) { scale_.fZ = row[2].length(); - row[2].normalize(); + SkVector3Normalize(row[2]); shear_.fY /= scale_.fZ; shear_.fZ /= scale_.fZ; diff --git a/flow/matrix_decomposition_unittests.cc b/flow/matrix_decomposition_unittests.cc index 3c1b7d6c9b77b..3b9f8ed815ff6 100644 --- a/flow/matrix_decomposition_unittests.cc +++ b/flow/matrix_decomposition_unittests.cc @@ -95,8 +95,7 @@ TEST(MatrixDecomposition, Combination) { } TEST(MatrixDecomposition, ScaleFloatError) { - // Strange behavior under 0.000245 due to underflow issues. - for (float scale = 0.000245f; scale < 2.0f; scale += 0.000001f) { + for (float scale = 0.0001f; scale < 2.0f; scale += 0.000001f) { SkMatrix44 matrix = SkMatrix44::I(); matrix.setScale(scale, scale, 1.0f); diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 0091d5bf02361..db0b6dd43e975 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -67,8 +67,6 @@ source_set("common") { "io_manager.h", "isolate_configuration.cc", "isolate_configuration.h", - "picture_serializer.cc", - "picture_serializer.h", "platform_view.cc", "platform_view.h", "rasterizer.cc", diff --git a/shell/common/picture_serializer.cc b/shell/common/picture_serializer.cc deleted file mode 100644 index b62e96d74f0a1..0000000000000 --- a/shell/common/picture_serializer.cc +++ /dev/null @@ -1,16 +0,0 @@ -// 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 "flutter/shell/common/picture_serializer.h" - -#include "third_party/skia/include/core/SkStream.h" - -namespace shell { - -void SerializePicture(const std::string& path, SkPicture* picture) { - SkFILEWStream stream(path.c_str()); - picture->serialize(&stream); -} - -} // namespace shell diff --git a/shell/common/picture_serializer.h b/shell/common/picture_serializer.h deleted file mode 100644 index 0416b2f0c6277..0000000000000 --- a/shell/common/picture_serializer.h +++ /dev/null @@ -1,18 +0,0 @@ -// 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 SHELL_GPU_PICTURE_SERIALIZER_H_ -#define SHELL_GPU_PICTURE_SERIALIZER_H_ - -#include - -#include "third_party/skia/include/core/SkPicture.h" - -namespace shell { - -void SerializePicture(const std::string& path, SkPicture* picture); - -} // namespace shell - -#endif // SHELL_GPU_PICTURE_SERIALIZER_H_ diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 6f0ddd53a1907..d3d78c6d72c8c 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -13,6 +13,10 @@ #include "third_party/skia/include/core/SkSurfaceCharacterization.h" #include "third_party/skia/include/utils/SkBase64.h" +#ifdef ERROR +#undef ERROR +#endif + namespace shell { Rasterizer::Rasterizer(blink::TaskRunners task_runners) @@ -114,7 +118,7 @@ bool Rasterizer::DrawToSurface(flow::LayerTree& layer_tree) { surface_->GetContext(), canvas, surface_->GetRootTransformation(), true); if (canvas) { - canvas->clear(SK_ColorBLACK); + canvas->clear(SK_ColorTRANSPARENT); } if (compositor_frame && compositor_frame->Raster(layer_tree, false)) { @@ -173,6 +177,7 @@ static sk_sp ScreenshotLayerTreeAsImage( auto snapshot_surface = CreateSnapshotSurface(surface_context, tree->frame_size()); if (snapshot_surface == nullptr) { + FML_LOG(ERROR) << "Screenshot: unable to create snapshot surface"; return nullptr; } @@ -186,23 +191,25 @@ static sk_sp ScreenshotLayerTreeAsImage( auto frame = compositor_context.AcquireFrame( surface_context, canvas, root_surface_transformation, false); - canvas->clear(SK_ColorBLACK); + canvas->clear(SK_ColorTRANSPARENT); frame->Raster(*tree, true); canvas->flush(); // Prepare an image from the surface, this image may potentially be on th GPU. auto potentially_gpu_snapshot = snapshot_surface->makeImageSnapshot(); if (!potentially_gpu_snapshot) { + FML_LOG(ERROR) << "Screenshot: unable to make image screenshot"; return nullptr; } // Copy the GPU image snapshot into CPU memory. auto cpu_snapshot = potentially_gpu_snapshot->makeRasterImage(); if (!cpu_snapshot) { + FML_LOG(ERROR) << "Screenshot: unable to make raster image"; return nullptr; } - // If the caller want the pixels to be compressed, there is a Skia utilitiy to + // If the caller want the pixels to be compressed, there is a Skia utility to // compress to PNG. Use that. if (compressed) { return cpu_snapshot->encodeToData(); @@ -211,6 +218,7 @@ static sk_sp ScreenshotLayerTreeAsImage( // Copy it into a bitmap and return the same. SkPixmap pixmap; if (!cpu_snapshot->peekPixels(&pixmap)) { + FML_LOG(ERROR) << "Screenshot: unable to obtain bitmap pixels"; return nullptr; } @@ -222,7 +230,7 @@ Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( bool base64_encode) { auto layer_tree = GetLastLayerTree(); if (layer_tree == nullptr) { - FML_DLOG(INFO) << "Last layer tree was null when screenshotting."; + FML_LOG(ERROR) << "Last layer tree was null when screenshotting."; return {}; } @@ -246,7 +254,7 @@ Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( } if (data == nullptr) { - FML_DLOG(INFO) << "Sceenshot data was null."; + FML_LOG(ERROR) << "Screenshot data was null."; return {}; } diff --git a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index 7136457ffca47..ae3a1381e230a 100644 --- a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -158,7 +158,7 @@ public boolean sendKeyEvent(KeyEvent event) { int character = event.getUnicodeChar(); if (character != 0) { int selStart = Math.max(0, Selection.getSelectionStart(mEditable)); - int selEnd = Selection.getSelectionEnd(mEditable); + int selEnd = Math.max(0, Selection.getSelectionEnd(mEditable)); if (selEnd != selStart) mEditable.delete(selStart, selEnd); mEditable.insert(selStart, String.valueOf((char) character)); diff --git a/shell/platform/android/io/flutter/view/FlutterMain.java b/shell/platform/android/io/flutter/view/FlutterMain.java index 2ac9347f18955..49d3b01707633 100644 --- a/shell/platform/android/io/flutter/view/FlutterMain.java +++ b/shell/platform/android/io/flutter/view/FlutterMain.java @@ -262,15 +262,7 @@ private static void initResources(Context applicationContext) { sResourceExtractor = new ResourceExtractor(context); - // Search for the icudtl.dat file at the old and new locations. - // TODO(jsimmons): remove the old location when all tools have been updated. - Set sharedAssets = listAssets(applicationContext, SHARED_ASSET_DIR); - String icuAssetPath; - if (sharedAssets.contains(SHARED_ASSET_ICU_DATA)) { - icuAssetPath = SHARED_ASSET_DIR + File.separator + SHARED_ASSET_ICU_DATA; - } else { - icuAssetPath = SHARED_ASSET_ICU_DATA; - } + String icuAssetPath = SHARED_ASSET_DIR + File.separator + SHARED_ASSET_ICU_DATA; sResourceExtractor.addResource(icuAssetPath); sIcuDataPath = PathUtils.getDataDirectory(applicationContext) + File.separator + icuAssetPath; diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index 0acaa6c4e894c..8a46370248365 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -12,6 +12,7 @@ import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.database.ContentObserver; +import android.graphics.PixelFormat; import android.provider.Settings; import android.net.Uri; import android.os.Handler; @@ -69,8 +70,6 @@ public interface Provider { private static final String TAG = "FlutterView"; - private static final String ACTION_DISCOVER = "io.flutter.view.DISCOVER"; - static final class ViewportMetrics { float devicePixelRatio = 1.0f; int physicalWidth = 0; @@ -96,7 +95,6 @@ static final class ViewportMetrics { private final BasicMessageChannel mFlutterLifecycleChannel; private final BasicMessageChannel mFlutterSystemChannel; private final BasicMessageChannel mFlutterSettingsChannel; - private final BroadcastReceiver mDiscoveryReceiver; private final List mActivityLifecycleListeners; private final List mFirstFrameListeners; private final AtomicLong nextTextureId = new AtomicLong(0L); @@ -131,20 +129,11 @@ public FlutterView(Context context, AttributeSet attrs, FlutterNativeView native } mNativeView.attachViewAndActivity(this, activity); - int color = 0xFF000000; - TypedValue typedValue = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.colorBackground, typedValue, true); - if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) { - color = typedValue.data; - } - // TODO(abarth): Consider letting the developer override this color. - final int backgroundColor = color; - mSurfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { assertAttached(); - nativeSurfaceCreated(mNativeView.get(), holder.getSurface(), backgroundColor); + nativeSurfaceCreated(mNativeView.get(), holder.getSurface()); } @Override @@ -183,13 +172,6 @@ public void surfaceDestroyed(SurfaceHolder holder) { setLocale(getResources().getConfiguration().locale); setUserSettings(); - - if ((context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { - mDiscoveryReceiver = new DiscoveryReceiver(); - context.registerReceiver(mDiscoveryReceiver, new IntentFilter(ACTION_DISCOVER)); - } else { - mDiscoveryReceiver = null; - } } private void encodeKeyEvent(KeyEvent event, Map message) { @@ -295,6 +277,26 @@ public void removeFirstFrameListener(FirstFrameListener listener) { mFirstFrameListeners.remove(listener); } + /** + * Updates this to support rendering as a transparent {@link SurfaceView}. + * + * Sets it on top of its window. The background color still needs to be + * controlled from within the Flutter UI itself. + */ + public void enableTransparentBackground() { + setZOrderOnTop(true); + getHolder().setFormat(PixelFormat.TRANSPARENT); + } + + /** + * Reverts this back to the {@link SurfaceView} defaults, at the back of its + * window and opaque. + */ + public void disableTransparentBackground() { + setZOrderOnTop(false); + getHolder().setFormat(PixelFormat.OPAQUE); + } + public void setInitialRoute(String route) { mFlutterNavigationChannel.invokeMethod("setInitialRoute", route); } @@ -332,9 +334,6 @@ float getDevicePixelRatio() { public FlutterNativeView detach() { if (!isAttached()) return null; - if (mDiscoveryReceiver != null) { - getContext().unregisterReceiver(mDiscoveryReceiver); - } getHolder().removeCallback(mSurfaceCallback); mNativeView.detach(); @@ -347,10 +346,6 @@ public void destroy() { if (!isAttached()) return; - if (mDiscoveryReceiver != null) { - getContext().unregisterReceiver(mDiscoveryReceiver); - } - getHolder().removeCallback(mSurfaceCallback); mNativeView.destroy(); @@ -651,8 +646,7 @@ public Bitmap getBitmap() { return nativeGetBitmap(mNativeView.get()); } - private static native void nativeSurfaceCreated(long nativePlatformViewAndroid, Surface surface, - int backgroundColor); + private static native void nativeSurfaceCreated(long nativePlatformViewAndroid, Surface surface); private static native void nativeSurfaceChanged(long nativePlatformViewAndroid, int width, int height); @@ -946,28 +940,6 @@ public void setMessageHandler(String channel, BinaryMessageHandler handler) { mNativeView.setMessageHandler(channel, handler); } - /** - * Broadcast receiver used to discover active Flutter instances. - * - * This is used by the `flutter` tool to find the observatory ports for all the - * active Flutter views. We dump the data to the logs and the tool scrapes the - * log lines for the data. - */ - private class DiscoveryReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - URI observatoryUri = URI.create(FlutterNativeView.getObservatoryUri()); - JSONObject discover = new JSONObject(); - try { - discover.put("id", getContext().getPackageName()); - discover.put("observatoryPort", observatoryUri.getPort()); - Log.i(TAG, "DISCOVER: " + discover); // The tool looks for this data. See - // android_device.dart. - } catch (JSONException e) { - } - } - } - /** * Listener will be called on the Android UI thread once when Flutter renders * the first frame. @@ -997,9 +969,19 @@ final class SurfaceTextureRegistryEntry implements TextureRegistry.SurfaceTextur this.surfaceTexture.setOnFrameAvailableListener(new SurfaceTexture.OnFrameAvailableListener() { @Override public void onFrameAvailable(SurfaceTexture texture) { + if (released) { + // Even though we make sure to unregister the callback before releasing, as of Android O + // SurfaceTexture has a data race when accessing the callback, so the callback may + // still be called by a stale reference after released==true and mNativeView==null. + return; + } nativeMarkTextureFrameAvailable(mNativeView.get(), SurfaceTextureRegistryEntry.this.id); } - }); + }, + // The callback relies on being executed on the UI thread (unsynchronised read of mNativeView + // and also the engine code check for platform thread in Shell::OnPlatformViewMarkTextureFrameAvailable), + // so we explicitly pass a Handler for the current thread. + new Handler()); } @Override @@ -1019,6 +1001,9 @@ public void release() { } released = true; nativeUnregisterTexture(mNativeView.get(), id); + // Otherwise onFrameAvailableListener might be called after mNativeView==null + // (https://github.com/flutter/flutter/issues/20951). See also the check in onFrameAvailable. + surfaceTexture.setOnFrameAvailableListener(null); surfaceTexture.release(); } } diff --git a/shell/platform/android/platform_view_android_jni.cc b/shell/platform/android/platform_view_android_jni.cc index 315ac0b55bdc0..6dd4b9ab3350a 100644 --- a/shell/platform/android/platform_view_android_jni.cc +++ b/shell/platform/android/platform_view_android_jni.cc @@ -176,8 +176,7 @@ static jstring GetObservatoryUri(JNIEnv* env, jclass clazz) { static void SurfaceCreated(JNIEnv* env, jobject jcaller, jlong shell_holder, - jobject jsurface, - jint backgroundColor) { + jobject jsurface) { // Note: This frame ensures that any local references used by // ANativeWindow_fromSurface are released immediately. This is needed as a // workaround for https://code.google.com/p/android/issues/detail?id=68174 @@ -638,7 +637,7 @@ bool PlatformViewAndroid::Register(JNIEnv* env) { static const JNINativeMethod view_methods[] = { { .name = "nativeSurfaceCreated", - .signature = "(JLandroid/view/Surface;I)V", + .signature = "(JLandroid/view/Surface;)V", .fnPtr = reinterpret_cast(&shell::SurfaceCreated), }, {