From 33e53de6ca2253ebfc1bc0501ab992cb915e16df Mon Sep 17 00:00:00 2001 From: Tomaž Vajngerl Date: Tue, 16 Dec 2014 22:56:46 +0900 Subject: android: remove old and unused LOAndroid and LOAndroid2 Change-Id: Ib25c4bb29081ae51a3b06a6fe2af76749ec8ea46 --- android/experimental/LOAndroid/.gitignore | 4 - android/experimental/LOAndroid/.idea/.name | 1 - android/experimental/LOAndroid/.idea/compiler.xml | 23 - .../.idea/copyright/profiles_settings.xml | 3 - android/experimental/LOAndroid/.idea/encodings.xml | 5 - android/experimental/LOAndroid/.idea/gradle.xml | 18 - .../.idea/libraries/appcompat_v7_19_1_0.xml | 10 - .../.idea/libraries/support_v4_19_1_0.xml | 11 - android/experimental/LOAndroid/.idea/misc.xml | 146 -- android/experimental/LOAndroid/.idea/modules.xml | 10 - .../LOAndroid/.idea/scopes/scope_settings.xml | 5 - android/experimental/LOAndroid/.idea/vcs.xml | 7 - android/experimental/LOAndroid/LOAndroid.iml | 12 - android/experimental/LOAndroid/app/.gitignore | 1 - android/experimental/LOAndroid/app/app.iml | 77 -- android/experimental/LOAndroid/app/build.gradle | 24 - .../experimental/LOAndroid/app/proguard-rules.txt | 17 - .../LOAndroid/app/src/main/AndroidManifest.xml | 25 - .../src/main/java/org/libreoffice/LOKitShell.java | 22 - .../main/java/org/libreoffice/MainActivity.java | 36 - .../main/java/org/libreoffice/MainLayerView.java | 26 - .../org/mozilla/gecko/TouchEventInterceptor.java | 14 - .../java/org/mozilla/gecko/ZoomConstraints.java | 46 - .../src/main/java/org/mozilla/gecko/gfx/Axis.java | 420 ------ .../java/org/mozilla/gecko/gfx/BitmapUtils.java | 368 ----- .../org/mozilla/gecko/gfx/BufferedCairoImage.java | 69 - .../java/org/mozilla/gecko/gfx/CairoGLInfo.java | 35 - .../java/org/mozilla/gecko/gfx/CairoImage.java | 28 - .../java/org/mozilla/gecko/gfx/CairoUtils.java | 51 - .../mozilla/gecko/gfx/DisplayPortCalculator.java | 777 ----------- .../org/mozilla/gecko/gfx/DisplayPortMetrics.java | 78 -- .../org/mozilla/gecko/gfx/DrawTimingQueue.java | 95 -- .../main/java/org/mozilla/gecko/gfx/FloatSize.java | 54 - .../java/org/mozilla/gecko/gfx/GLController.java | 354 ----- .../org/mozilla/gecko/gfx/GeckoLayerClient.java | 1000 -------------- .../gecko/gfx/ImmutableViewportMetrics.java | 374 ----- .../mozilla/gecko/gfx/InputConnectionHandler.java | 22 - .../main/java/org/mozilla/gecko/gfx/IntSize.java | 91 -- .../mozilla/gecko/gfx/JavaPanZoomController.java | 1461 -------------------- .../src/main/java/org/mozilla/gecko/gfx/Layer.java | 207 --- .../mozilla/gecko/gfx/LayerMarginsAnimator.java | 324 ----- .../java/org/mozilla/gecko/gfx/LayerRenderer.java | 722 ---------- .../main/java/org/mozilla/gecko/gfx/LayerView.java | 692 --------- .../java/org/mozilla/gecko/gfx/Overscroll.java | 21 - .../mozilla/gecko/gfx/OverscrollEdgeEffect.java | 130 -- .../org/mozilla/gecko/gfx/PanZoomController.java | 49 - .../java/org/mozilla/gecko/gfx/PanZoomTarget.java | 33 - .../java/org/mozilla/gecko/gfx/PanningPerfAPI.java | 123 -- .../java/org/mozilla/gecko/gfx/PointUtils.java | 51 - .../mozilla/gecko/gfx/ProgressiveUpdateData.java | 33 - .../main/java/org/mozilla/gecko/gfx/RectUtils.java | 126 -- .../java/org/mozilla/gecko/gfx/RenderTask.java | 80 -- .../java/org/mozilla/gecko/gfx/ScrollbarLayer.java | 297 ---- .../gecko/gfx/SimpleScaleGestureDetector.java | 322 ----- .../org/mozilla/gecko/gfx/SingleTileLayer.java | 153 -- .../mozilla/gecko/gfx/SubdocumentScrollHelper.java | 148 -- .../main/java/org/mozilla/gecko/gfx/TextLayer.java | 69 - .../org/mozilla/gecko/gfx/TextureGenerator.java | 75 - .../java/org/mozilla/gecko/gfx/TextureReaper.java | 51 - .../main/java/org/mozilla/gecko/gfx/TileLayer.java | 177 --- .../org/mozilla/gecko/gfx/TouchEventHandler.java | 306 ---- .../java/org/mozilla/gecko/gfx/ViewTransform.java | 34 - .../java/org/mozilla/gecko/gfx/VirtualLayer.java | 36 - .../gecko/mozglue/DirectBufferAllocator.java | 51 - .../org/mozilla/gecko/util/EventDispatcher.java | 115 -- .../java/org/mozilla/gecko/util/FloatUtils.java | 43 - .../mozilla/gecko/util/GeckoBackgroundThread.java | 55 - .../org/mozilla/gecko/util/GeckoEventListener.java | 14 - .../mozilla/gecko/util/GeckoEventResponder.java | 16 - .../java/org/mozilla/gecko/util/ThreadUtils.java | 169 --- .../java/org/mozilla/gecko/util/UiAsyncTask.java | 86 -- .../app/src/main/res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 0 bytes .../src/main/res/drawable-hdpi/ic_status_logo.png | Bin 1864 -> 0 bytes .../app/src/main/res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 0 bytes .../src/main/res/drawable-mdpi/ic_status_logo.png | Bin 1533 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_status_logo.png | Bin 2049 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 19388 -> 0 bytes .../app/src/main/res/layout/activity_main.xml | 15 - .../LOAndroid/app/src/main/res/menu/main.xml | 9 - .../app/src/main/res/values-w820dp/dimens.xml | 6 - .../LOAndroid/app/src/main/res/values/colors.xml | 95 -- .../LOAndroid/app/src/main/res/values/dimens.xml | 5 - .../LOAndroid/app/src/main/res/values/strings.xml | 8 - .../LOAndroid/app/src/main/res/values/styles.xml | 8 - android/experimental/LOAndroid/build.gradle | 16 - android/experimental/LOAndroid/gradle.properties | 18 - .../LOAndroid/gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - android/experimental/LOAndroid/gradlew | 164 --- android/experimental/LOAndroid/gradlew.bat | 90 -- android/experimental/LOAndroid/settings.gradle | 1 - android/experimental/LOAndroid2/.gitignore | 4 - android/experimental/LOAndroid2/.idea/.name | 1 - android/experimental/LOAndroid2/.idea/compiler.xml | 23 - .../.idea/copyright/profiles_settings.xml | 3 - .../experimental/LOAndroid2/.idea/encodings.xml | 5 - android/experimental/LOAndroid2/.idea/gradle.xml | 18 - android/experimental/LOAndroid2/.idea/misc.xml | 41 - android/experimental/LOAndroid2/.idea/modules.xml | 11 - .../LOAndroid2/.idea/scopes/scope_settings.xml | 5 - android/experimental/LOAndroid2/.idea/vcs.xml | 7 - android/experimental/LOAndroid2/LOAndroid2.iml | 19 - android/experimental/LOAndroid2/app/.gitignore | 1 - android/experimental/LOAndroid2/app/app.iml | 66 - android/experimental/LOAndroid2/app/build.gradle | 23 - .../experimental/LOAndroid2/app/proguard-rules.txt | 17 - .../LOAndroid2/app/src/main/AndroidManifest.xml | 24 - .../app/src/main/java/org/libreoffice/LOEvent.java | 67 - .../src/main/java/org/libreoffice/LOKitShell.java | 131 -- .../src/main/java/org/libreoffice/LOKitThread.java | 157 --- .../org/libreoffice/LibreOfficeMainActivity.java | 102 -- .../java/org/mozilla/gecko/GeckoEventListener.java | 44 - .../org/mozilla/gecko/gfx/BufferedCairoImage.java | 105 -- .../java/org/mozilla/gecko/gfx/CairoGLInfo.java | 72 - .../java/org/mozilla/gecko/gfx/CairoImage.java | 58 - .../java/org/mozilla/gecko/gfx/CairoUtils.java | 85 -- .../org/mozilla/gecko/gfx/CheckerboardImage.java | 170 --- .../mozilla/gecko/gfx/FlexibleGLSurfaceView.java | 218 --- .../main/java/org/mozilla/gecko/gfx/FloatSize.java | 99 -- .../java/org/mozilla/gecko/gfx/GLController.java | 279 ---- .../main/java/org/mozilla/gecko/gfx/GLThread.java | 181 --- .../org/mozilla/gecko/gfx/GeckoLayerClient.java | 398 ------ .../gecko/gfx/GeckoSoftwareLayerClient.java | 242 ---- .../mozilla/gecko/gfx/InputConnectionHandler.java | 15 - .../main/java/org/mozilla/gecko/gfx/IntSize.java | 103 -- .../src/main/java/org/mozilla/gecko/gfx/Layer.java | 242 ---- .../java/org/mozilla/gecko/gfx/LayerClient.java | 81 -- .../org/mozilla/gecko/gfx/LayerController.java | 534 ------- .../java/org/mozilla/gecko/gfx/LayerRenderer.java | 689 --------- .../main/java/org/mozilla/gecko/gfx/LayerView.java | 230 --- .../java/org/mozilla/gecko/gfx/MultiTileLayer.java | 250 ---- .../org/mozilla/gecko/gfx/NinePatchTileLayer.java | 124 -- .../java/org/mozilla/gecko/gfx/PanningPerfAPI.java | 125 -- .../java/org/mozilla/gecko/gfx/PointUtils.java | 96 -- .../main/java/org/mozilla/gecko/gfx/RectUtils.java | 139 -- .../java/org/mozilla/gecko/gfx/ScrollbarLayer.java | 425 ------ .../org/mozilla/gecko/gfx/SingleTileLayer.java | 127 -- .../main/java/org/mozilla/gecko/gfx/SubTile.java | 15 - .../main/java/org/mozilla/gecko/gfx/TextLayer.java | 117 -- .../org/mozilla/gecko/gfx/TextureGenerator.java | 73 - .../java/org/mozilla/gecko/gfx/TextureReaper.java | 76 - .../main/java/org/mozilla/gecko/gfx/TileLayer.java | 256 ---- .../java/org/mozilla/gecko/gfx/ViewTransform.java | 51 - .../org/mozilla/gecko/gfx/ViewportMetrics.java | 306 ---- .../java/org/mozilla/gecko/gfx/VirtualLayer.java | 80 -- .../org/mozilla/gecko/gfx/WidgetTileLayer.java | 160 --- .../src/main/java/org/mozilla/gecko/ui/Axis.java | 271 ---- .../org/mozilla/gecko/ui/PanZoomController.java | 921 ------------ .../gecko/ui/SimpleScaleGestureDetector.java | 332 ----- .../mozilla/gecko/ui/SubdocumentScrollHelper.java | 140 -- .../java/org/mozilla/gecko/util/FloatUtils.java | 43 - .../app/src/main/res/drawable-hdpi/base.png | Bin 20684 -> 0 bytes .../app/src/main/res/drawable-hdpi/calc.png | Bin 20697 -> 0 bytes .../app/src/main/res/drawable-hdpi/d1.png | Bin 22661 -> 0 bytes .../app/src/main/res/drawable-hdpi/d2.png | Bin 27485 -> 0 bytes .../app/src/main/res/drawable-hdpi/d3.png | Bin 293 -> 0 bytes .../app/src/main/res/drawable-hdpi/d4.png | Bin 28043 -> 0 bytes .../app/src/main/res/drawable-hdpi/d5.png | Bin 33266 -> 0 bytes .../app/src/main/res/drawable-hdpi/d6.png | Bin 293 -> 0 bytes .../app/src/main/res/drawable-hdpi/d7.png | Bin 9942 -> 0 bytes .../app/src/main/res/drawable-hdpi/d8.png | Bin 11499 -> 0 bytes .../app/src/main/res/drawable-hdpi/d9.png | Bin 213 -> 0 bytes .../app/src/main/res/drawable-hdpi/draw.png | Bin 18445 -> 0 bytes .../app/src/main/res/drawable-hdpi/dummy_page.png | Bin 77517 -> 0 bytes .../app/src/main/res/drawable-hdpi/ic_launcher.png | Bin 9397 -> 0 bytes .../src/main/res/drawable-hdpi/ic_status_logo.png | Bin 1864 -> 0 bytes .../app/src/main/res/drawable-hdpi/impress.png | Bin 13936 -> 0 bytes .../app/src/main/res/drawable-hdpi/lo_icon.png | Bin 4475 -> 0 bytes .../app/src/main/res/drawable-hdpi/main.png | Bin 4380 -> 0 bytes .../app/src/main/res/drawable-hdpi/math.png | Bin 15370 -> 0 bytes .../app/src/main/res/drawable-hdpi/startcenter.png | Bin 4380 -> 0 bytes .../app/src/main/res/drawable-mdpi/background.png | Bin 18308 -> 0 bytes .../app/src/main/res/drawable-mdpi/base.png | Bin 20684 -> 0 bytes .../app/src/main/res/drawable-mdpi/calc.png | Bin 20697 -> 0 bytes .../app/src/main/res/drawable-mdpi/docu.png | Bin 203346 -> 0 bytes .../app/src/main/res/drawable-mdpi/draw.png | Bin 18445 -> 0 bytes .../app/src/main/res/drawable-mdpi/ic_launcher.png | Bin 5237 -> 0 bytes .../src/main/res/drawable-mdpi/ic_status_logo.png | Bin 1533 -> 0 bytes .../app/src/main/res/drawable-mdpi/impress.png | Bin 13936 -> 0 bytes .../app/src/main/res/drawable-mdpi/lo_icon.png | Bin 3255 -> 0 bytes .../app/src/main/res/drawable-mdpi/shadow.png | Bin 881 -> 0 bytes .../app/src/main/res/drawable-mdpi/writer.png | Bin 19535 -> 0 bytes .../app/src/main/res/drawable-xhdpi/base.png | Bin 20684 -> 0 bytes .../app/src/main/res/drawable-xhdpi/calc.png | Bin 20697 -> 0 bytes .../app/src/main/res/drawable-xhdpi/draw.png | Bin 18445 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_launcher.png | Bin 14383 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_status_logo.png | Bin 2049 -> 0 bytes .../app/src/main/res/drawable-xhdpi/impress.png | Bin 13936 -> 0 bytes .../app/src/main/res/drawable-xhdpi/writer.png | Bin 19535 -> 0 bytes .../src/main/res/drawable-xxhdpi/ic_launcher.png | Bin 19388 -> 0 bytes .../app/src/main/res/layout/activity_main.xml | 15 - .../LOAndroid2/app/src/main/res/menu/main.xml | 8 - .../app/src/main/res/values-w820dp/dimens.xml | 6 - .../LOAndroid2/app/src/main/res/values/colors.xml | 95 -- .../LOAndroid2/app/src/main/res/values/dimens.xml | 5 - .../LOAndroid2/app/src/main/res/values/strings.xml | 8 - .../LOAndroid2/app/src/main/res/values/styles.xml | 8 - android/experimental/LOAndroid2/build.gradle | 16 - android/experimental/LOAndroid2/gradle.properties | 18 - .../LOAndroid2/gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - android/experimental/LOAndroid2/gradlew | 164 --- android/experimental/LOAndroid2/gradlew.bat | 90 -- android/experimental/LOAndroid2/settings.gradle | 1 - 205 files changed, 20206 deletions(-) delete mode 100644 android/experimental/LOAndroid/.gitignore delete mode 100644 android/experimental/LOAndroid/.idea/.name delete mode 100644 android/experimental/LOAndroid/.idea/compiler.xml delete mode 100644 android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml delete mode 100644 android/experimental/LOAndroid/.idea/encodings.xml delete mode 100644 android/experimental/LOAndroid/.idea/gradle.xml delete mode 100644 android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml delete mode 100644 android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml delete mode 100644 android/experimental/LOAndroid/.idea/misc.xml delete mode 100644 android/experimental/LOAndroid/.idea/modules.xml delete mode 100644 android/experimental/LOAndroid/.idea/scopes/scope_settings.xml delete mode 100644 android/experimental/LOAndroid/.idea/vcs.xml delete mode 100644 android/experimental/LOAndroid/LOAndroid.iml delete mode 100644 android/experimental/LOAndroid/app/.gitignore delete mode 100644 android/experimental/LOAndroid/app/app.iml delete mode 100644 android/experimental/LOAndroid/app/build.gradle delete mode 100644 android/experimental/LOAndroid/app/proguard-rules.txt delete mode 100644 android/experimental/LOAndroid/app/src/main/AndroidManifest.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java delete mode 100644 android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/menu/main.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/values/colors.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/values/dimens.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/values/strings.xml delete mode 100644 android/experimental/LOAndroid/app/src/main/res/values/styles.xml delete mode 100644 android/experimental/LOAndroid/build.gradle delete mode 100644 android/experimental/LOAndroid/gradle.properties delete mode 100644 android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar delete mode 100644 android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties delete mode 100644 android/experimental/LOAndroid/gradlew delete mode 100644 android/experimental/LOAndroid/gradlew.bat delete mode 100644 android/experimental/LOAndroid/settings.gradle delete mode 100644 android/experimental/LOAndroid2/.gitignore delete mode 100644 android/experimental/LOAndroid2/.idea/.name delete mode 100644 android/experimental/LOAndroid2/.idea/compiler.xml delete mode 100644 android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml delete mode 100644 android/experimental/LOAndroid2/.idea/encodings.xml delete mode 100644 android/experimental/LOAndroid2/.idea/gradle.xml delete mode 100644 android/experimental/LOAndroid2/.idea/misc.xml delete mode 100644 android/experimental/LOAndroid2/.idea/modules.xml delete mode 100644 android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml delete mode 100644 android/experimental/LOAndroid2/.idea/vcs.xml delete mode 100644 android/experimental/LOAndroid2/LOAndroid2.iml delete mode 100644 android/experimental/LOAndroid2/app/.gitignore delete mode 100644 android/experimental/LOAndroid2/app/app.iml delete mode 100644 android/experimental/LOAndroid2/app/build.gradle delete mode 100644 android/experimental/LOAndroid2/app/proguard-rules.txt delete mode 100644 android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/menu/main.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/values/colors.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/values/strings.xml delete mode 100644 android/experimental/LOAndroid2/app/src/main/res/values/styles.xml delete mode 100644 android/experimental/LOAndroid2/build.gradle delete mode 100644 android/experimental/LOAndroid2/gradle.properties delete mode 100644 android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar delete mode 100644 android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties delete mode 100755 android/experimental/LOAndroid2/gradlew delete mode 100644 android/experimental/LOAndroid2/gradlew.bat delete mode 100644 android/experimental/LOAndroid2/settings.gradle (limited to 'android') diff --git a/android/experimental/LOAndroid/.gitignore b/android/experimental/LOAndroid/.gitignore deleted file mode 100644 index d6bfc95b184b..000000000000 --- a/android/experimental/LOAndroid/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.gradle -/local.properties -/.idea/workspace.xml -.DS_Store diff --git a/android/experimental/LOAndroid/.idea/.name b/android/experimental/LOAndroid/.idea/.name deleted file mode 100644 index 3300c569c980..000000000000 --- a/android/experimental/LOAndroid/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -LOAndroid \ No newline at end of file diff --git a/android/experimental/LOAndroid/.idea/compiler.xml b/android/experimental/LOAndroid/.idea/compiler.xml deleted file mode 100644 index 217af471a9e6..000000000000 --- a/android/experimental/LOAndroid/.idea/compiler.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml b/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3377d4..000000000000 --- a/android/experimental/LOAndroid/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid/.idea/encodings.xml b/android/experimental/LOAndroid/.idea/encodings.xml deleted file mode 100644 index e206d70d8595..000000000000 --- a/android/experimental/LOAndroid/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/android/experimental/LOAndroid/.idea/gradle.xml b/android/experimental/LOAndroid/.idea/gradle.xml deleted file mode 100644 index 736c7b5cffcc..000000000000 --- a/android/experimental/LOAndroid/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml b/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml deleted file mode 100644 index 970e5fa480a9..000000000000 --- a/android/experimental/LOAndroid/.idea/libraries/appcompat_v7_19_1_0.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml b/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml deleted file mode 100644 index 1ca1ac68ad96..000000000000 --- a/android/experimental/LOAndroid/.idea/libraries/support_v4_19_1_0.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid/.idea/misc.xml b/android/experimental/LOAndroid/.idea/misc.xml deleted file mode 100644 index 589a3ed5fd78..000000000000 --- a/android/experimental/LOAndroid/.idea/misc.xml +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - - - - - - - - - - Abstraction issues - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - 5050 - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid/.idea/modules.xml b/android/experimental/LOAndroid/.idea/modules.xml deleted file mode 100644 index f08135d5d6bf..000000000000 --- a/android/experimental/LOAndroid/.idea/modules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml b/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b8433b..000000000000 --- a/android/experimental/LOAndroid/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid/.idea/vcs.xml b/android/experimental/LOAndroid/.idea/vcs.xml deleted file mode 100644 index def6a6a18457..000000000000 --- a/android/experimental/LOAndroid/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/android/experimental/LOAndroid/LOAndroid.iml b/android/experimental/LOAndroid/LOAndroid.iml deleted file mode 100644 index edb62a65fa47..000000000000 --- a/android/experimental/LOAndroid/LOAndroid.iml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid/app/.gitignore b/android/experimental/LOAndroid/app/.gitignore deleted file mode 100644 index 796b96d1c402..000000000000 --- a/android/experimental/LOAndroid/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/android/experimental/LOAndroid/app/app.iml b/android/experimental/LOAndroid/app/app.iml deleted file mode 100644 index d3a780b91527..000000000000 --- a/android/experimental/LOAndroid/app/app.iml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid/app/build.gradle b/android/experimental/LOAndroid/app/build.gradle deleted file mode 100644 index 7e98dd4c48c9..000000000000 --- a/android/experimental/LOAndroid/app/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -apply plugin: 'android' - -android { - compileSdkVersion 19 - buildToolsVersion "19.1.0" - - defaultConfig { - minSdkVersion 15 - targetSdkVersion 19 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:19.+' -} diff --git a/android/experimental/LOAndroid/app/proguard-rules.txt b/android/experimental/LOAndroid/app/proguard-rules.txt deleted file mode 100644 index 0b0be289afc1..000000000000 --- a/android/experimental/LOAndroid/app/proguard-rules.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/quikee/Programs/android-sdk-linux/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} \ No newline at end of file diff --git a/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml b/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml deleted file mode 100644 index 3120a69b4247..000000000000 --- a/android/experimental/LOAndroid/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java deleted file mode 100644 index cd429d66a2ad..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/LOKitShell.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.libreoffice; - - -import org.mozilla.gecko.gfx.LayerView; - -public class LOKitShell { - public static int getDpi() { - return 96; - } - - public static int getScreenDepth() { - return 24; - } - - public static LayerView getLayerView() { - return null; - } - - public static float computeRenderIntegrity() { - return 0.0f; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java deleted file mode 100644 index 1963ad2c2b43..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainActivity.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.libreoffice; - -import android.app.Activity; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; - - -public class MainActivity extends Activity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - } - - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.main, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_settings) { - return true; - } - return super.onOptionsItemSelected(item); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java b/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java deleted file mode 100644 index 5721df2806b3..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/libreoffice/MainLayerView.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.libreoffice; - -import android.content.Context; -import android.os.Handler; -import android.util.AttributeSet; - -import org.mozilla.gecko.gfx.LayerView; -import org.mozilla.gecko.util.ThreadUtils; - -public class MainLayerView extends LayerView { - - public MainLayerView(Context context) { - super(context); - init(context); - } - - public MainLayerView(Context context, AttributeSet attrs) { - super(context, attrs); - init(context); - } - - private void init(Context context) { - ThreadUtils.setUiThread(Thread.currentThread(), new Handler()); - } - -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java deleted file mode 100644 index 41a71dfa5f88..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/TouchEventInterceptor.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import android.view.MotionEvent; -import android.view.View; - -public interface TouchEventInterceptor extends View.OnTouchListener { - /** Override this method for a chance to consume events before the view or its children */ - public boolean onInterceptTouchEvent(View view, MotionEvent event); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java deleted file mode 100644 index 40d1817c9301..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/ZoomConstraints.java +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko; - -import org.json.JSONException; -import org.json.JSONObject; - -public final class ZoomConstraints { - private final boolean mAllowZoom; - private final float mDefaultZoom; - private final float mMinZoom; - private final float mMaxZoom; - - public ZoomConstraints(boolean allowZoom) { - mAllowZoom = allowZoom; - mDefaultZoom = 0.0f; - mMinZoom = 0.0f; - mMaxZoom = 0.0f; - } - - ZoomConstraints(JSONObject message) throws JSONException { - mAllowZoom = message.getBoolean("allowZoom"); - mDefaultZoom = (float)message.getDouble("defaultZoom"); - mMinZoom = (float)message.getDouble("minZoom"); - mMaxZoom = (float)message.getDouble("maxZoom"); - } - - public final boolean getAllowZoom() { - return mAllowZoom; - } - - public final float getDefaultZoom() { - return mDefaultZoom; - } - - public final float getMinZoom() { - return mMinZoom; - } - - public final float getMaxZoom() { - return mMaxZoom; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java deleted file mode 100644 index 103ee5173539..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Axis.java +++ /dev/null @@ -1,420 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.PrefsHelper; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.util.FloatUtils; - -import org.json.JSONArray; - -import android.util.Log; -import android.view.View; - -import java.util.HashMap; -import java.util.Map; - -/** - * This class represents the physics for one axis of movement (i.e. either - * horizontal or vertical). It tracks the different properties of movement - * like displacement, velocity, viewport dimensions, etc. pertaining to - * a particular axis. - */ -abstract class Axis { - private static final String LOGTAG = "GeckoAxis"; - - private static final String PREF_SCROLLING_FRICTION_SLOW = "ui.scrolling.friction_slow"; - private static final String PREF_SCROLLING_FRICTION_FAST = "ui.scrolling.friction_fast"; - private static final String PREF_SCROLLING_MAX_EVENT_ACCELERATION = "ui.scrolling.max_event_acceleration"; - private static final String PREF_SCROLLING_OVERSCROLL_DECEL_RATE = "ui.scrolling.overscroll_decel_rate"; - private static final String PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT = "ui.scrolling.overscroll_snap_limit"; - private static final String PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE = "ui.scrolling.min_scrollable_distance"; - - // This fraction of velocity remains after every animation frame when the velocity is low. - private static float FRICTION_SLOW; - // This fraction of velocity remains after every animation frame when the velocity is high. - private static float FRICTION_FAST; - // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST - // to FRICTION_SLOW. - private static float VELOCITY_THRESHOLD; - // The maximum velocity change factor between events, per ms, in %. - // Direction changes are excluded. - private static float MAX_EVENT_ACCELERATION; - - // The rate of deceleration when the surface has overscrolled. - private static float OVERSCROLL_DECEL_RATE; - // The percentage of the surface which can be overscrolled before it must snap back. - private static float SNAP_LIMIT; - - // The minimum amount of space that must be present for an axis to be considered scrollable, - // in pixels. - private static float MIN_SCROLLABLE_DISTANCE; - - private static float getFloatPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (float)(value == null || value < 0 ? defaultValue : value) / 1000f; - } - - private static int getIntPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (value == null || value < 0 ? defaultValue : value); - } - - static void initPrefs() { - final String[] prefs = { PREF_SCROLLING_FRICTION_FAST, - PREF_SCROLLING_FRICTION_SLOW, - PREF_SCROLLING_MAX_EVENT_ACCELERATION, - PREF_SCROLLING_OVERSCROLL_DECEL_RATE, - PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, - PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE }; - - /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() { - Map mPrefs = new HashMap(); - - @Override public void prefValue(String name, int value) { - mPrefs.put(name, value); - } - - @Override public void finish() { - setPrefs(mPrefs); - } - });*/ - } - - static final float MS_PER_FRAME = 1000.0f / 60.0f; - static final long NS_PER_FRAME = Math.round(1000000000f / 60f); - private static final float FRAMERATE_MULTIPLIER = (1000f/60f) / MS_PER_FRAME; - private static final int FLING_VELOCITY_POINTS = 8; - - // The values we use for friction are based on a 16.6ms frame, adjust them to currentNsPerFrame: - static float getFrameAdjustedFriction(float baseFriction, long currentNsPerFrame) { - float framerateMultiplier = (float)currentNsPerFrame / NS_PER_FRAME; - return (float)Math.pow(Math.E, (Math.log(baseFriction) / framerateMultiplier)); - } - - static void setPrefs(Map prefs) { - FRICTION_SLOW = getFloatPref(prefs, PREF_SCROLLING_FRICTION_SLOW, 850); - FRICTION_FAST = getFloatPref(prefs, PREF_SCROLLING_FRICTION_FAST, 970); - VELOCITY_THRESHOLD = 10 / FRAMERATE_MULTIPLIER; - MAX_EVENT_ACCELERATION = getFloatPref(prefs, PREF_SCROLLING_MAX_EVENT_ACCELERATION, /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() > 300 ? 100 : 40); - OVERSCROLL_DECEL_RATE = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_DECEL_RATE, 40); - SNAP_LIMIT = getFloatPref(prefs, PREF_SCROLLING_OVERSCROLL_SNAP_LIMIT, 300); - MIN_SCROLLABLE_DISTANCE = getFloatPref(prefs, PREF_SCROLLING_MIN_SCROLLABLE_DISTANCE, 500); - Log.i(LOGTAG, "Prefs: " + FRICTION_SLOW + "," + FRICTION_FAST + "," + VELOCITY_THRESHOLD + "," - + MAX_EVENT_ACCELERATION + "," + OVERSCROLL_DECEL_RATE + "," + SNAP_LIMIT + "," + MIN_SCROLLABLE_DISTANCE); - } - - static { - // set the scrolling parameters to default values on startup - setPrefs(null); - } - - private enum FlingStates { - STOPPED, - PANNING, - FLINGING, - } - - private enum Overscroll { - NONE, - MINUS, // Overscrolled in the negative direction - PLUS, // Overscrolled in the positive direction - BOTH, // Overscrolled in both directions (page is zoomed to smaller than screen) - } - - private final SubdocumentScrollHelper mSubscroller; - - private int mOverscrollMode; /* Default to only overscrolling if we're allowed to scroll in a direction */ - private float mFirstTouchPos; /* Position of the first touch event on the current drag. */ - private float mTouchPos; /* Position of the most recent touch event on the current drag. */ - private float mLastTouchPos; /* Position of the touch event before touchPos. */ - private float mVelocity; /* Velocity in this direction; pixels per animation frame. */ - private float[] mRecentVelocities; /* Circular buffer of recent velocities since last touch start. */ - private int mRecentVelocityCount; /* Number of values put into mRecentVelocities (unbounded). */ - private boolean mScrollingDisabled; /* Whether movement on this axis is locked. */ - private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */ - private float mDisplacement; - - private FlingStates mFlingState = FlingStates.STOPPED; /* The fling state we're in on this axis. */ - - protected abstract float getOrigin(); - protected abstract float getViewportLength(); - protected abstract float getPageStart(); - protected abstract float getPageLength(); - protected abstract float getMarginStart(); - protected abstract float getMarginEnd(); - protected abstract boolean marginsHidden(); - - Axis(SubdocumentScrollHelper subscroller) { - mSubscroller = subscroller; - mOverscrollMode = View.OVER_SCROLL_IF_CONTENT_SCROLLS; - mRecentVelocities = new float[FLING_VELOCITY_POINTS]; - } - - // Implementors can override these to show effects when the axis overscrolls - protected void overscrollFling(float velocity) { } - protected void overscrollPan(float displacement) { } - - public void setOverScrollMode(int overscrollMode) { - mOverscrollMode = overscrollMode; - } - - public int getOverScrollMode() { - return mOverscrollMode; - } - - private float getViewportEnd() { - return getOrigin() + getViewportLength(); - } - - private float getPageEnd() { - return getPageStart() + getPageLength(); - } - - void startTouch(float pos) { - mVelocity = 0.0f; - mScrollingDisabled = false; - mFirstTouchPos = mTouchPos = mLastTouchPos = pos; - mRecentVelocityCount = 0; - } - - float panDistance(float currentPos) { - return currentPos - mFirstTouchPos; - } - - void setScrollingDisabled(boolean disabled) { - mScrollingDisabled = disabled; - } - - void saveTouchPos() { - mLastTouchPos = mTouchPos; - } - - void updateWithTouchAt(float pos, float timeDelta) { - float newVelocity = (mTouchPos - pos) / timeDelta * MS_PER_FRAME; - - mRecentVelocities[mRecentVelocityCount % FLING_VELOCITY_POINTS] = newVelocity; - mRecentVelocityCount++; - - // If there's a direction change, or current velocity is very low, - // allow setting of the velocity outright. Otherwise, use the current - // velocity and a maximum change factor to set the new velocity. - boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f / FRAMERATE_MULTIPLIER; - boolean directionChange = (mVelocity > 0) != (newVelocity > 0); - if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) { - mVelocity = newVelocity; - } else { - float maxChange = Math.abs(mVelocity * timeDelta * MAX_EVENT_ACCELERATION); - mVelocity = Math.min(mVelocity + maxChange, Math.max(mVelocity - maxChange, newVelocity)); - } - - mTouchPos = pos; - } - - boolean overscrolled() { - return getOverscroll() != Overscroll.NONE; - } - - private Overscroll getOverscroll() { - boolean minus = (getOrigin() < getPageStart()); - boolean plus = (getViewportEnd() > getPageEnd()); - if (minus && plus) { - return Overscroll.BOTH; - } else if (minus) { - return Overscroll.MINUS; - } else if (plus) { - return Overscroll.PLUS; - } else { - return Overscroll.NONE; - } - } - - // Returns the amount that the page has been overscrolled. If the page hasn't been - // overscrolled on this axis, returns 0. - private float getExcess() { - switch (getOverscroll()) { - case MINUS: return getPageStart() - getOrigin(); - case PLUS: return getViewportEnd() - getPageEnd(); - case BOTH: return (getViewportEnd() - getPageEnd()) + (getPageStart() - getOrigin()); - default: return 0.0f; - } - } - - /* - * Returns true if the page is zoomed in to some degree along this axis such that scrolling is - * possible and this axis has not been scroll locked while panning. Otherwise, returns false. - */ - boolean scrollable() { - // If we're scrolling a subdocument, ignore the viewport length restrictions (since those - // apply to the top-level document) and only take into account axis locking. - if (mSubscroller.scrolling()) { - return !mScrollingDisabled; - } - - // if we are axis locked, return false - if (mScrollingDisabled) { - return false; - } - - // if there are margins on this axis but they are currently hidden, - // we must be able to scroll in order to make them visible, so allow - // scrolling in that case - if (marginsHidden()) { - return true; - } - - // there is scrollable space, and we're not disabled, or the document fits the viewport - // but we always allow overscroll anyway - return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE || - getOverScrollMode() == View.OVER_SCROLL_ALWAYS; - } - - /* - * Returns the resistance, as a multiplier, that should be taken into account when - * tracking or pinching. - */ - float getEdgeResistance(boolean forPinching) { - float excess = getExcess(); - if (excess > 0.0f && (getOverscroll() == Overscroll.BOTH || !forPinching)) { - // excess can be greater than viewport length, but the resistance - // must never drop below 0.0 - return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength()); - } - return 1.0f; - } - - /* Returns the velocity. If the axis is locked, returns 0. */ - float getRealVelocity() { - return scrollable() ? mVelocity : 0f; - } - - void startPan() { - mFlingState = FlingStates.PANNING; - } - - private float calculateFlingVelocity() { - int usablePoints = Math.min(mRecentVelocityCount, FLING_VELOCITY_POINTS); - if (usablePoints <= 1) { - return mVelocity; - } - float average = 0; - for (int i = 0; i < usablePoints; i++) { - average += mRecentVelocities[i]; - } - return average / usablePoints; - } - - void startFling(boolean stopped) { - mDisableSnap = mSubscroller.scrolling(); - - if (stopped) { - mFlingState = FlingStates.STOPPED; - } else { - mVelocity = calculateFlingVelocity(); - mFlingState = FlingStates.FLINGING; - } - } - - /* Advances a fling animation by one step. */ - boolean advanceFling(long realNsPerFrame) { - if (mFlingState != FlingStates.FLINGING) { - return false; - } - if (mSubscroller.scrolling() && !mSubscroller.lastScrollSucceeded()) { - // if the subdocument stopped scrolling, it's because it reached the end - // of the subdocument. we don't do overscroll on subdocuments, so there's - // no point in continuing this fling. - return false; - } - - float excess = getExcess(); - Overscroll overscroll = getOverscroll(); - boolean decreasingOverscroll = false; - if ((overscroll == Overscroll.MINUS && mVelocity > 0) || - (overscroll == Overscroll.PLUS && mVelocity < 0)) - { - decreasingOverscroll = true; - } - - if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f) || decreasingOverscroll) { - // If we aren't overscrolled, just apply friction. - if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) { - mVelocity *= getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame); - } else { - float t = mVelocity / VELOCITY_THRESHOLD; - mVelocity *= FloatUtils.interpolate(getFrameAdjustedFriction(FRICTION_SLOW, realNsPerFrame), - getFrameAdjustedFriction(FRICTION_FAST, realNsPerFrame), t); - } - } else { - // Otherwise, decrease the velocity linearly. - float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT); - float overscrollDecelRate = getFrameAdjustedFriction(OVERSCROLL_DECEL_RATE, realNsPerFrame); - if (overscroll == Overscroll.MINUS) { - mVelocity = Math.min((mVelocity + overscrollDecelRate) * elasticity, 0.0f); - } else { // must be Overscroll.PLUS - mVelocity = Math.max((mVelocity - overscrollDecelRate) * elasticity, 0.0f); - } - } - - return true; - } - - void stopFling() { - mVelocity = 0.0f; - mFlingState = FlingStates.STOPPED; - } - - // Performs displacement of the viewport position according to the current velocity. - void displace() { - // if this isn't scrollable just return - if (!scrollable()) - return; - - if (mFlingState == FlingStates.PANNING) - mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance(false); - else - mDisplacement += mVelocity * getEdgeResistance(false); - - // if overscroll is disabled and we're trying to overscroll, reset the displacement - // to remove any excess. Using getExcess alone isn't enough here since it relies on - // getOverscroll which doesn't take into account any new displacment being applied. - // If we using a subscroller, we don't want to alter the scrolling being done - if (getOverScrollMode() == View.OVER_SCROLL_NEVER && !mSubscroller.scrolling()) { - float originalDisplacement = mDisplacement; - - if (mDisplacement + getOrigin() < getPageStart() - getMarginStart()) { - mDisplacement = getPageStart() - getMarginStart() - getOrigin(); - } else if (mDisplacement + getViewportEnd() > getPageEnd() + getMarginEnd()) { - mDisplacement = getPageEnd() - getMarginEnd() - getViewportEnd(); - } - - // Return the amount of overscroll so that the overscroll controller can draw it for us - if (originalDisplacement != mDisplacement) { - if (mFlingState == FlingStates.FLINGING) { - overscrollFling(mVelocity / MS_PER_FRAME * 1000); - stopFling(); - } else if (mFlingState == FlingStates.PANNING) { - overscrollPan(originalDisplacement - mDisplacement); - } - } - } - } - - float resetDisplacement() { - float d = mDisplacement; - mDisplacement = 0.0f; - return d; - } - - void setAutoscrollVelocity(float velocity) { - if (mFlingState != FlingStates.STOPPED) { - Log.e(LOGTAG, "Setting autoscroll velocity while in a fling is not allowed!"); - return; - } - mVelocity = velocity; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java deleted file mode 100644 index 9dba802f6d38..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BitmapUtils.java +++ /dev/null @@ -1,368 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.ThreadUtils; -import org.mozilla.gecko.util.UiAsyncTask; -//import org.mozilla.gecko.util.GeckoJarReader; -//import org.mozilla.gecko.R; - -import org.libreoffice.R; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.BitmapDrawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.util.Base64; -import android.util.Log; -import android.text.TextUtils; - -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.Field; -import java.lang.NoSuchFieldException; -import java.net.MalformedURLException; -import java.net.URL; - -public final class BitmapUtils { - private static final String LOGTAG = "GeckoBitmapUtils"; - - private BitmapUtils() {} - - public interface BitmapLoader { - public void onBitmapFound(Drawable d); - } - - public static void getDrawable(final Context context, final String data, final BitmapLoader loader) { - if (TextUtils.isEmpty(data)) { - loader.onBitmapFound(null); - return; - } - - if (data.startsWith("data")) { - BitmapDrawable d = new BitmapDrawable(context.getResources(), getBitmapFromDataURI(data)); - loader.onBitmapFound(d); - return; - } - - if (data.startsWith("jar:") || data.startsWith("file://")) { - (new UiAsyncTask(ThreadUtils.getBackgroundHandler()) { - @Override - public Drawable doInBackground(Void... params) { - try { - //if (data.startsWith("jar:jar")) { - // return GeckoJarReader.getBitmapDrawable(context.getResources(), data); - //} - - // Don't attempt to validate the JAR signature when loading an add-on icon - //if (data.startsWith("jar:file")) { - // return GeckoJarReader.getBitmapDrawable(context.getResources(), Uri.decode(data)); - //} - - URL url = new URL(data); - InputStream is = (InputStream) url.getContent(); - try { - return Drawable.createFromStream(is, "src"); - } finally { - is.close(); - } - } catch (Exception e) { - Log.w(LOGTAG, "Unable to set icon", e); - } - return null; - } - - @Override - public void onPostExecute(Drawable drawable) { - loader.onBitmapFound(drawable); - } - }).execute(); - return; - } - - if(data.startsWith("-moz-icon://")) { - Uri imageUri = Uri.parse(data); - String resource = imageUri.getSchemeSpecificPart(); - resource = resource.substring(resource.lastIndexOf('/') + 1); - - try { - Drawable d = context.getPackageManager().getApplicationIcon(resource); - loader.onBitmapFound(d); - } catch(Exception ex) { } - - return; - } - - if(data.startsWith("drawable://")) { - Uri imageUri = Uri.parse(data); - int id = getResource(imageUri, R.drawable.ic_status_logo); - Drawable d = context.getResources().getDrawable(id); - - loader.onBitmapFound(d); - return; - } - - loader.onBitmapFound(null); - } - - public static Bitmap decodeByteArray(byte[] bytes) { - return decodeByteArray(bytes, null); - } - - public static Bitmap decodeByteArray(byte[] bytes, BitmapFactory.Options options) { - return decodeByteArray(bytes, 0, bytes.length, options); - } - - public static Bitmap decodeByteArray(byte[] bytes, int offset, int length) { - return decodeByteArray(bytes, offset, length, null); - } - - public static Bitmap decodeByteArray(byte[] bytes, int offset, int length, BitmapFactory.Options options) { - if (bytes.length <= 0) { - throw new IllegalArgumentException("bytes.length " + bytes.length - + " must be a positive number"); - } - - Bitmap bitmap = null; - try { - bitmap = BitmapFactory.decodeByteArray(bytes, offset, length, options); - } catch (OutOfMemoryError e) { - Log.e(LOGTAG, "decodeByteArray(bytes.length=" + bytes.length - + ", options= " + options + ") OOM!", e); - return null; - } - - if (bitmap == null) { - Log.w(LOGTAG, "decodeByteArray() returning null because BitmapFactory returned null"); - return null; - } - - if (bitmap.getWidth() <= 0 || bitmap.getHeight() <= 0) { - Log.w(LOGTAG, "decodeByteArray() returning null because BitmapFactory returned " - + "a bitmap with dimensions " + bitmap.getWidth() - + "x" + bitmap.getHeight()); - return null; - } - - return bitmap; - } - - public static Bitmap decodeStream(InputStream inputStream) { - try { - return BitmapFactory.decodeStream(inputStream); - } catch (OutOfMemoryError e) { - Log.e(LOGTAG, "decodeStream() OOM!", e); - return null; - } - } - - public static Bitmap decodeUrl(Uri uri) { - return decodeUrl(uri.toString()); - } - - public static Bitmap decodeUrl(String urlString) { - URL url; - - try { - url = new URL(urlString); - } catch(MalformedURLException e) { - Log.w(LOGTAG, "decodeUrl: malformed URL " + urlString); - return null; - } - - return decodeUrl(url); - } - - public static Bitmap decodeUrl(URL url) { - InputStream stream = null; - - try { - stream = url.openStream(); - } catch(IOException e) { - Log.w(LOGTAG, "decodeUrl: IOException downloading " + url); - return null; - } - - if (stream == null) { - Log.w(LOGTAG, "decodeUrl: stream not found downloading " + url); - return null; - } - - Bitmap bitmap = decodeStream(stream); - - try { - stream.close(); - } catch(IOException e) { - Log.w(LOGTAG, "decodeUrl: IOException closing stream " + url, e); - } - - return bitmap; - } - - public static Bitmap decodeResource(Context context, int id) { - return decodeResource(context, id, null); - } - - public static Bitmap decodeResource(Context context, int id, BitmapFactory.Options options) { - Resources resources = context.getResources(); - try { - return BitmapFactory.decodeResource(resources, id, options); - } catch (OutOfMemoryError e) { - Log.e(LOGTAG, "decodeResource() OOM! Resource id=" + id, e); - return null; - } - } - - public static int getDominantColor(Bitmap source) { - return getDominantColor(source, true); - } - - public static int getDominantColor(Bitmap source, boolean applyThreshold) { - if (source == null) - return Color.argb(255,255,255,255); - - // Keep track of how many times a hue in a given bin appears in the image. - // Hue values range [0 .. 360), so dividing by 10, we get 36 bins. - int[] colorBins = new int[36]; - - // The bin with the most colors. Initialize to -1 to prevent accidentally - // thinking the first bin holds the dominant color. - int maxBin = -1; - - // Keep track of sum hue/saturation/value per hue bin, which we'll use to - // compute an average to for the dominant color. - float[] sumHue = new float[36]; - float[] sumSat = new float[36]; - float[] sumVal = new float[36]; - float[] hsv = new float[3]; - - int height = source.getHeight(); - int width = source.getWidth(); - int[] pixels = new int[width * height]; - source.getPixels(pixels, 0, width, 0, 0, width, height); - for (int row = 0; row < height; row++) { - for (int col = 0; col < width; col++) { - int c = pixels[col + row * width]; - // Ignore pixels with a certain transparency. - if (Color.alpha(c) < 128) - continue; - - Color.colorToHSV(c, hsv); - - // If a threshold is applied, ignore arbitrarily chosen values for "white" and "black". - if (applyThreshold && (hsv[1] <= 0.35f || hsv[2] <= 0.35f)) - continue; - - // We compute the dominant color by putting colors in bins based on their hue. - int bin = (int) Math.floor(hsv[0] / 10.0f); - - // Update the sum hue/saturation/value for this bin. - sumHue[bin] = sumHue[bin] + hsv[0]; - sumSat[bin] = sumSat[bin] + hsv[1]; - sumVal[bin] = sumVal[bin] + hsv[2]; - - // Increment the number of colors in this bin. - colorBins[bin]++; - - // Keep track of the bin that holds the most colors. - if (maxBin < 0 || colorBins[bin] > colorBins[maxBin]) - maxBin = bin; - } - } - - // maxBin may never get updated if the image holds only transparent and/or black/white pixels. - if (maxBin < 0) - return Color.argb(255,255,255,255); - - // Return a color with the average hue/saturation/value of the bin with the most colors. - hsv[0] = sumHue[maxBin]/colorBins[maxBin]; - hsv[1] = sumSat[maxBin]/colorBins[maxBin]; - hsv[2] = sumVal[maxBin]/colorBins[maxBin]; - return Color.HSVToColor(hsv); - } - - /** - * Decodes a bitmap from a Base64 data URI. - * - * @param dataURI a Base64-encoded data URI string - * @return the decoded bitmap, or null if the data URI is invalid - */ - public static Bitmap getBitmapFromDataURI(String dataURI) { - String base64 = dataURI.substring(dataURI.indexOf(',') + 1); - try { - byte[] raw = Base64.decode(base64, Base64.DEFAULT); - return BitmapUtils.decodeByteArray(raw); - } catch (Exception e) { - Log.e(LOGTAG, "exception decoding bitmap from data URI: " + dataURI, e); - } - return null; - } - - public static Bitmap getBitmapFromDrawable(Drawable drawable) { - if (drawable instanceof BitmapDrawable) { - return ((BitmapDrawable) drawable).getBitmap(); - } - - int width = drawable.getIntrinsicWidth(); - width = width > 0 ? width : 1; - int height = drawable.getIntrinsicHeight(); - height = height > 0 ? height : 1; - - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); - - return bitmap; - } - - public static int getResource(Uri resourceUrl, int defaultIcon) { - int icon = defaultIcon; - - final String scheme = resourceUrl.getScheme(); - if ("drawable".equals(scheme)) { - String resource = resourceUrl.getSchemeSpecificPart(); - resource = resource.substring(resource.lastIndexOf('/') + 1); - - try { - return Integer.parseInt(resource); - } catch(NumberFormatException ex) { - // This isn't a resource id, try looking for a string - } - - try { - final Class drawableClass = R.drawable.class; - final Field f = drawableClass.getField(resource); - icon = f.getInt(null); - } catch (final NoSuchFieldException e1) { - - // just means the resource doesn't exist for fennec. Check in Android resources - try { - final Class drawableClass = android.R.drawable.class; - final Field f = drawableClass.getField(resource); - icon = f.getInt(null); - } catch (final NoSuchFieldException e2) { - // This drawable doesn't seem to exist... - } catch(Exception e3) { - Log.i(LOGTAG, "Exception getting drawable", e3); - } - - } catch (Exception e4) { - Log.i(LOGTAG, "Exception getting drawable", e4); - } - - resourceUrl = null; - } - return icon; - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java deleted file mode 100644 index 307f41204256..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.mozglue.DirectBufferAllocator; - -import android.graphics.Bitmap; -import android.util.Log; - -import java.nio.ByteBuffer; - -/** A Cairo image that simply saves a buffer of pixel data. */ -public class BufferedCairoImage extends CairoImage { - private ByteBuffer mBuffer; - private IntSize mSize; - private int mFormat; - - private static String LOGTAG = "GeckoBufferedCairoImage"; - - /** Creates a buffered Cairo image from a byte buffer. */ - public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) { - setBuffer(inBuffer, inWidth, inHeight, inFormat); - } - - /** Creates a buffered Cairo image from an Android bitmap. */ - public BufferedCairoImage(Bitmap bitmap) { - setBitmap(bitmap); - } - - private synchronized void freeBuffer() { - mBuffer = DirectBufferAllocator.free(mBuffer); - } - - @Override - public void destroy() { - try { - freeBuffer(); - } catch (Exception ex) { - Log.e(LOGTAG, "error clearing buffer: ", ex); - } - } - - @Override - public ByteBuffer getBuffer() { return mBuffer; } - @Override - public IntSize getSize() { return mSize; } - @Override - public int getFormat() { return mFormat; } - - - public void setBuffer(ByteBuffer buffer, int width, int height, int format) { - freeBuffer(); - mBuffer = buffer; - mSize = new IntSize(width, height); - mFormat = format; - } - - public void setBitmap(Bitmap bitmap) { - mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig()); - mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight()); - - int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat); - mBuffer = DirectBufferAllocator.allocate(mSize.getArea() * bpp); - bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer()); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java deleted file mode 100644 index 472c1d29f792..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import javax.microedition.khronos.opengles.GL10; - -/** Information needed to render Cairo bitmaps using OpenGL ES. */ -public class CairoGLInfo { - public final int internalFormat; - public final int format; - public final int type; - - public CairoGLInfo(int cairoFormat) { - switch (cairoFormat) { - case CairoImage.FORMAT_ARGB32: - internalFormat = format = GL10.GL_RGBA; type = GL10.GL_UNSIGNED_BYTE; - break; - case CairoImage.FORMAT_RGB24: - internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_BYTE; - break; - case CairoImage.FORMAT_RGB16_565: - internalFormat = format = GL10.GL_RGB; type = GL10.GL_UNSIGNED_SHORT_5_6_5; - break; - case CairoImage.FORMAT_A8: - case CairoImage.FORMAT_A1: - throw new RuntimeException("Cairo FORMAT_A1 and FORMAT_A8 unsupported"); - default: - throw new RuntimeException("Unknown Cairo format"); - } - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java deleted file mode 100644 index 5a18a4bb1995..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import java.nio.ByteBuffer; - -/* - * A bitmap with pixel data in one of the formats that Cairo understands. - */ -public abstract class CairoImage { - public abstract ByteBuffer getBuffer(); - - public abstract void destroy(); - - public abstract IntSize getSize(); - public abstract int getFormat(); - - public static final int FORMAT_INVALID = -1; - public static final int FORMAT_ARGB32 = 0; - public static final int FORMAT_RGB24 = 1; - public static final int FORMAT_A8 = 2; - public static final int FORMAT_A1 = 3; - public static final int FORMAT_RGB16_565 = 4; -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java deleted file mode 100644 index 48c449f05e5c..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Bitmap; - -/** - * Utility methods useful when displaying Cairo bitmaps using OpenGL ES. - */ -public class CairoUtils { - private CairoUtils() { /* Don't call me. */ } - - public static int bitsPerPixelForCairoFormat(int cairoFormat) { - switch (cairoFormat) { - case CairoImage.FORMAT_A1: return 1; - case CairoImage.FORMAT_A8: return 8; - case CairoImage.FORMAT_RGB16_565: return 16; - case CairoImage.FORMAT_RGB24: return 24; - case CairoImage.FORMAT_ARGB32: return 32; - default: - throw new RuntimeException("Unknown Cairo format"); - } - } - - public static int bitmapConfigToCairoFormat(Bitmap.Config config) { - if (config == null) - return CairoImage.FORMAT_ARGB32; /* Droid Pro fix. */ - - switch (config) { - case ALPHA_8: return CairoImage.FORMAT_A8; - case ARGB_4444: throw new RuntimeException("ARGB_444 unsupported"); - case ARGB_8888: return CairoImage.FORMAT_ARGB32; - case RGB_565: return CairoImage.FORMAT_RGB16_565; - default: throw new RuntimeException("Unknown Skia bitmap config"); - } - } - - public static Bitmap.Config cairoFormatTobitmapConfig(int format) { - switch (format) { - case CairoImage.FORMAT_A8: return Bitmap.Config.ALPHA_8; - case CairoImage.FORMAT_ARGB32: return Bitmap.Config.ARGB_8888; - case CairoImage.FORMAT_RGB16_565: return Bitmap.Config.RGB_565; - default: - throw new RuntimeException("Unknown CairoImage format"); - } - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java deleted file mode 100644 index f101dfbdb75f..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortCalculator.java +++ /dev/null @@ -1,777 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.PrefsHelper; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.util.FloatUtils; - -import org.json.JSONArray; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.FloatMath; -import android.util.Log; - -import java.util.HashMap; -import java.util.Map; - -final class DisplayPortCalculator { - private static final String LOGTAG = "GeckoDisplayPort"; - private static final PointF ZERO_VELOCITY = new PointF(0, 0); - - // Keep this in sync with the TILEDLAYERBUFFER_TILE_SIZE defined in gfx/layers/TiledLayerBuffer.h - private static final int TILE_SIZE = 256; - - private static final String PREF_DISPLAYPORT_STRATEGY = "gfx.displayport.strategy"; - private static final String PREF_DISPLAYPORT_FM_MULTIPLIER = "gfx.displayport.strategy_fm.multiplier"; - private static final String PREF_DISPLAYPORT_FM_DANGER_X = "gfx.displayport.strategy_fm.danger_x"; - private static final String PREF_DISPLAYPORT_FM_DANGER_Y = "gfx.displayport.strategy_fm.danger_y"; - private static final String PREF_DISPLAYPORT_VB_MULTIPLIER = "gfx.displayport.strategy_vb.multiplier"; - private static final String PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_vb.threshold"; - private static final String PREF_DISPLAYPORT_VB_REVERSE_BUFFER = "gfx.displayport.strategy_vb.reverse_buffer"; - private static final String PREF_DISPLAYPORT_VB_DANGER_X_BASE = "gfx.displayport.strategy_vb.danger_x_base"; - private static final String PREF_DISPLAYPORT_VB_DANGER_Y_BASE = "gfx.displayport.strategy_vb.danger_y_base"; - private static final String PREF_DISPLAYPORT_VB_DANGER_X_INCR = "gfx.displayport.strategy_vb.danger_x_incr"; - private static final String PREF_DISPLAYPORT_VB_DANGER_Y_INCR = "gfx.displayport.strategy_vb.danger_y_incr"; - private static final String PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD = "gfx.displayport.strategy_pb.threshold"; - - private static DisplayPortStrategy sStrategy = new VelocityBiasStrategy(null); - - static DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - return sStrategy.calculate(metrics, (velocity == null ? ZERO_VELOCITY : velocity)); - } - - static boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - if (displayPort == null) { - return true; - } - return sStrategy.aboutToCheckerboard(metrics, (velocity == null ? ZERO_VELOCITY : velocity), displayPort); - } - - static boolean drawTimeUpdate(long millis, int pixels) { - return sStrategy.drawTimeUpdate(millis, pixels); - } - - static void resetPageState() { - sStrategy.resetPageState(); - } - - static void initPrefs() { - final String[] prefs = { PREF_DISPLAYPORT_STRATEGY, - PREF_DISPLAYPORT_FM_MULTIPLIER, - PREF_DISPLAYPORT_FM_DANGER_X, - PREF_DISPLAYPORT_FM_DANGER_Y, - PREF_DISPLAYPORT_VB_MULTIPLIER, - PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD, - PREF_DISPLAYPORT_VB_REVERSE_BUFFER, - PREF_DISPLAYPORT_VB_DANGER_X_BASE, - PREF_DISPLAYPORT_VB_DANGER_Y_BASE, - PREF_DISPLAYPORT_VB_DANGER_X_INCR, - PREF_DISPLAYPORT_VB_DANGER_Y_INCR, - PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD }; - - /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() { - private Map mValues = new HashMap(); - - @Override public void prefValue(String pref, int value) { - mValues.put(pref, value); - } - - @Override public void finish() { - setStrategy(mValues); - } - });*/ - } - - /** - * Set the active strategy to use. - * See the gfx.displayport.strategy pref in mobile/android/app/mobile.js to see the - * mapping between ints and strategies. - */ - static boolean setStrategy(Map prefs) { - Integer strategy = prefs.get(PREF_DISPLAYPORT_STRATEGY); - if (strategy == null) { - return false; - } - - switch (strategy) { - case 0: - sStrategy = new FixedMarginStrategy(prefs); - break; - case 1: - sStrategy = new VelocityBiasStrategy(prefs); - break; - case 2: - sStrategy = new DynamicResolutionStrategy(prefs); - break; - case 3: - sStrategy = new NoMarginStrategy(prefs); - break; - case 4: - sStrategy = new PredictionBiasStrategy(prefs); - break; - default: - Log.e(LOGTAG, "Invalid strategy index specified"); - return false; - } - Log.i(LOGTAG, "Set strategy " + sStrategy.toString()); - return true; - } - - private static float getFloatPref(Map prefs, String prefName, int defaultValue) { - Integer value = (prefs == null ? null : prefs.get(prefName)); - return (float)(value == null || value < 0 ? defaultValue : value) / 1000f; - } - - private static abstract class DisplayPortStrategy { - /** Calculates a displayport given a viewport and panning velocity. */ - public abstract DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity); - /** Returns true if a checkerboard is about to be visible and we should not throttle drawing. */ - public abstract boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort); - /** Notify the strategy of a new recorded draw time. Return false to turn off draw time recording. */ - public boolean drawTimeUpdate(long millis, int pixels) { return false; } - /** Reset any page-specific state stored, as the page being displayed has changed. */ - public void resetPageState() {} - } - - /** - * Return the dimensions for a rect that has area (width*height) that does not exceed the page size in the - * given metrics object. The area in the returned FloatSize may be less than width*height if the page is - * small, but it will never be larger than width*height. - * Note that this process may change the relative aspect ratio of the given dimensions. - */ - private static FloatSize reshapeForPage(float width, float height, ImmutableViewportMetrics metrics) { - // figure out how much of the desired buffer amount we can actually use on the horizontal axis - float usableWidth = Math.min(width, metrics.getPageWidth()); - // if we reduced the buffer amount on the horizontal axis, we should take that saved memory and - // use it on the vertical axis - float extraUsableHeight = (float)Math.floor(((width - usableWidth) * height) / usableWidth); - float usableHeight = Math.min(height + extraUsableHeight, metrics.getPageHeight()); - if (usableHeight < height && usableWidth == width) { - // and the reverse - if we shrunk the buffer on the vertical axis we can add it to the horizontal - float extraUsableWidth = (float)Math.floor(((height - usableHeight) * width) / usableHeight); - usableWidth = Math.min(width + extraUsableWidth, metrics.getPageWidth()); - } - return new FloatSize(usableWidth, usableHeight); - } - - /** - * Expand the given rect in all directions by a "danger zone". The size of the danger zone on an axis - * is the size of the view on that axis multiplied by the given multiplier. The expanded rect is then - * clamped to page bounds and returned. - */ - private static RectF expandByDangerZone(RectF rect, float dangerZoneXMultiplier, float dangerZoneYMultiplier, ImmutableViewportMetrics metrics) { - // calculate the danger zone amounts in pixels - float dangerZoneX = metrics.getWidth() * dangerZoneXMultiplier; - float dangerZoneY = metrics.getHeight() * dangerZoneYMultiplier; - rect = RectUtils.expand(rect, dangerZoneX, dangerZoneY); - // clamp to page bounds - return clampToPageBounds(rect, metrics); - } - - /** - * Expand the given margins such that when they are applied on the viewport, the resulting rect - * does not have any partial tiles, except when it is clipped by the page bounds. This assumes - * the tiles are TILE_SIZE by TILE_SIZE and start at the origin, such that there will always be - * a tile at (0,0)-(TILE_SIZE,TILE_SIZE)). - */ - private static DisplayPortMetrics getTileAlignedDisplayPortMetrics(RectF margins, float zoom, ImmutableViewportMetrics metrics) { - float left = metrics.viewportRectLeft - margins.left; - float top = metrics.viewportRectTop - margins.top; - float right = metrics.viewportRectRight + margins.right; - float bottom = metrics.viewportRectBottom + margins.bottom; - left = Math.max(metrics.pageRectLeft, TILE_SIZE * FloatMath.floor(left / TILE_SIZE)); - top = Math.max(metrics.pageRectTop, TILE_SIZE * FloatMath.floor(top / TILE_SIZE)); - right = Math.min(metrics.pageRectRight, TILE_SIZE * FloatMath.ceil(right / TILE_SIZE)); - bottom = Math.min(metrics.pageRectBottom, TILE_SIZE * FloatMath.ceil(bottom / TILE_SIZE)); - return new DisplayPortMetrics(left, top, right, bottom, zoom); - } - - /** - * Adjust the given margins so if they are applied on the viewport in the metrics, the resulting rect - * does not exceed the page bounds. This code will maintain the total margin amount for a given axis; - * it assumes that margins.left + metrics.getWidth() + margins.right is less than or equal to - * metrics.getPageWidth(); and the same for the y axis. - */ - private static RectF shiftMarginsForPageBounds(RectF margins, ImmutableViewportMetrics metrics) { - // check how much we're overflowing in each direction. note that at most one of leftOverflow - // and rightOverflow can be greater than zero, and at most one of topOverflow and bottomOverflow - // can be greater than zero, because of the assumption described in the method javadoc. - float leftOverflow = metrics.pageRectLeft - (metrics.viewportRectLeft - margins.left); - float rightOverflow = (metrics.viewportRectRight + margins.right) - metrics.pageRectRight; - float topOverflow = metrics.pageRectTop - (metrics.viewportRectTop - margins.top); - float bottomOverflow = (metrics.viewportRectBottom + margins.bottom) - metrics.pageRectBottom; - - // if the margins overflow the page bounds, shift them to other side on the same axis - if (leftOverflow > 0) { - margins.left -= leftOverflow; - margins.right += leftOverflow; - } else if (rightOverflow > 0) { - margins.right -= rightOverflow; - margins.left += rightOverflow; - } - if (topOverflow > 0) { - margins.top -= topOverflow; - margins.bottom += topOverflow; - } else if (bottomOverflow > 0) { - margins.bottom -= bottomOverflow; - margins.top += bottomOverflow; - } - return margins; - } - - /** - * Clamp the given rect to the page bounds and return it. - */ - private static RectF clampToPageBounds(RectF rect, ImmutableViewportMetrics metrics) { - if (rect.top < metrics.pageRectTop) rect.top = metrics.pageRectTop; - if (rect.left < metrics.pageRectLeft) rect.left = metrics.pageRectLeft; - if (rect.right > metrics.pageRectRight) rect.right = metrics.pageRectRight; - if (rect.bottom > metrics.pageRectBottom) rect.bottom = metrics.pageRectBottom; - return rect; - } - - /** - * This class implements the variation where we basically don't bother with a display port. - */ - private static class NoMarginStrategy extends DisplayPortStrategy { - NoMarginStrategy(Map prefs) { - // no prefs in this strategy - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - return new DisplayPortMetrics(metrics.viewportRectLeft, - metrics.viewportRectTop, - metrics.viewportRectRight, - metrics.viewportRectBottom, - metrics.zoomFactor); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - return true; - } - - @Override - public String toString() { - return "NoMarginStrategy"; - } - } - - /** - * This class implements the variation where we use a fixed-size margin on the display port. - * The margin is always 300 pixels in all directions, except when we are (a) approaching a page - * boundary, and/or (b) if we are limited by the page size. In these cases we try to maintain - * the area of the display port by (a) shifting the buffer to the other side on the same axis, - * and/or (b) increasing the buffer on the other axis to compensate for the reduced buffer on - * one axis. - */ - private static class FixedMarginStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private final float SIZE_MULTIPLIER; - - // If the visible rect is within the danger zone (measured as a fraction of the view size - // from the edge of the displayport) we start redrawing to minimize checkerboarding. - private final float DANGER_ZONE_X_MULTIPLIER; - private final float DANGER_ZONE_Y_MULTIPLIER; - - FixedMarginStrategy(Map prefs) { - SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_MULTIPLIER, 2000); - DANGER_ZONE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_X, 100); - DANGER_ZONE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_FM_DANGER_Y, 200); - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). we simultaneously need to make - // the display port as large as possible so that we redraw less. reshape the display - // port dimensions to accomplish this. - FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - float horizontalBuffer = usableSize.width - metrics.getWidth(); - float verticalBuffer = usableSize.height - metrics.getHeight(); - - // and now calculate the display port margins based on how much buffer we've decided to use and - // the page bounds, ensuring we use all of the available buffer amounts on one side or the other - // on any given axis. (i.e. if we're scrolled to the top of the page, the vertical buffer is - // entirely below the visible viewport, but if we're halfway down the page, the vertical buffer - // is split). - RectF margins = new RectF(); - margins.left = horizontalBuffer / 2.0f; - margins.right = horizontalBuffer - margins.left; - margins.top = verticalBuffer / 2.0f; - margins.bottom = verticalBuffer - margins.top; - margins = shiftMarginsForPageBounds(margins, metrics); - - return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // Increase the size of the viewport based on the danger zone multiplier (and clamp to page - // boundaries), and intersect it with the current displayport to determine whether we're - // close to checkerboarding. - RectF adjustedViewport = expandByDangerZone(metrics.getViewport(), DANGER_ZONE_X_MULTIPLIER, DANGER_ZONE_Y_MULTIPLIER, metrics); - return !displayPort.contains(adjustedViewport); - } - - @Override - public String toString() { - return "FixedMarginStrategy mult=" + SIZE_MULTIPLIER + ", dangerX=" + DANGER_ZONE_X_MULTIPLIER + ", dangerY=" + DANGER_ZONE_Y_MULTIPLIER; - } - } - - /** - * This class implements the variation with a small fixed-size margin with velocity bias. - * In this variation, the default margins are pretty small relative to the view size, but - * they are affected by the panning velocity. Specifically, if we are panning on one axis, - * we remove the margins on the other axis because we are likely axis-locked. Also once - * we are panning in one direction above a certain threshold velocity, we shift the buffer - * so that it is almost entirely in the direction of the pan, with a little bit in the - * reverse direction. - */ - private static class VelocityBiasStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private final float SIZE_MULTIPLIER; - // The velocity above which we apply the velocity bias - private final float VELOCITY_THRESHOLD; - // How much of the buffer to keep in the reverse direction of the velocity - private final float REVERSE_BUFFER; - // If the visible rect is within the danger zone we start redrawing to minimize - // checkerboarding. the danger zone amount is a linear function of the form: - // viewportsize * (base + velocity * incr) - // where base and incr are configurable values. - private final float DANGER_ZONE_BASE_X_MULTIPLIER; - private final float DANGER_ZONE_BASE_Y_MULTIPLIER; - private final float DANGER_ZONE_INCR_X_MULTIPLIER; - private final float DANGER_ZONE_INCR_Y_MULTIPLIER; - - VelocityBiasStrategy(Map prefs) { - SIZE_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_MULTIPLIER, 2000); - VELOCITY_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_VB_VELOCITY_THRESHOLD, 32); - REVERSE_BUFFER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_REVERSE_BUFFER, 200); - DANGER_ZONE_BASE_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_BASE, 1000); - DANGER_ZONE_BASE_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_BASE, 1000); - DANGER_ZONE_INCR_X_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_X_INCR, 0); - DANGER_ZONE_INCR_Y_MULTIPLIER = getFloatPref(prefs, PREF_DISPLAYPORT_VB_DANGER_Y_INCR, 0); - } - - /** - * Split the given amounts into margins based on the VELOCITY_THRESHOLD and REVERSE_BUFFER values. - * If the velocity is above the VELOCITY_THRESHOLD on an axis, split the amount into REVERSE_BUFFER - * and 1.0 - REVERSE_BUFFER fractions. The REVERSE_BUFFER fraction is set as the margin in the - * direction opposite to the velocity, and the remaining fraction is set as the margin in the direction - * of the velocity. If the velocity is lower than VELOCITY_THRESHOLD, split the amount evenly into the - * two margins on that axis. - */ - private RectF velocityBiasedMargins(float xAmount, float yAmount, PointF velocity) { - RectF margins = new RectF(); - - if (velocity.x > VELOCITY_THRESHOLD) { - margins.left = xAmount * REVERSE_BUFFER; - } else if (velocity.x < -VELOCITY_THRESHOLD) { - margins.left = xAmount * (1.0f - REVERSE_BUFFER); - } else { - margins.left = xAmount / 2.0f; - } - margins.right = xAmount - margins.left; - - if (velocity.y > VELOCITY_THRESHOLD) { - margins.top = yAmount * REVERSE_BUFFER; - } else if (velocity.y < -VELOCITY_THRESHOLD) { - margins.top = yAmount * (1.0f - REVERSE_BUFFER); - } else { - margins.top = yAmount / 2.0f; - } - margins.bottom = yAmount - margins.top; - - return margins; - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // but if we're panning on one axis, set the margins for the other axis to zero since we are likely - // axis locked and won't be displaying that extra area. - if (Math.abs(velocity.x) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.y, 0)) { - displayPortHeight = metrics.getHeight(); - } else if (Math.abs(velocity.y) > VELOCITY_THRESHOLD && FloatUtils.fuzzyEquals(velocity.x, 0)) { - displayPortWidth = metrics.getWidth(); - } - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). - displayPortWidth = Math.min(displayPortWidth, metrics.getPageWidth()); - displayPortHeight = Math.min(displayPortHeight, metrics.getPageHeight()); - float horizontalBuffer = displayPortWidth - metrics.getWidth(); - float verticalBuffer = displayPortHeight - metrics.getHeight(); - - // split the buffer amounts into margins based on velocity, and shift it to - // take into account the page bounds - RectF margins = velocityBiasedMargins(horizontalBuffer, verticalBuffer, velocity); - margins = shiftMarginsForPageBounds(margins, metrics); - - return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // calculate the danger zone amounts based on the prefs - float dangerZoneX = metrics.getWidth() * (DANGER_ZONE_BASE_X_MULTIPLIER + (velocity.x * DANGER_ZONE_INCR_X_MULTIPLIER)); - float dangerZoneY = metrics.getHeight() * (DANGER_ZONE_BASE_Y_MULTIPLIER + (velocity.y * DANGER_ZONE_INCR_Y_MULTIPLIER)); - // clamp it such that when added to the viewport, they don't exceed page size. - // this is a prerequisite to calling shiftMarginsForPageBounds as we do below. - dangerZoneX = Math.min(dangerZoneX, metrics.getPageWidth() - metrics.getWidth()); - dangerZoneY = Math.min(dangerZoneY, metrics.getPageHeight() - metrics.getHeight()); - - // split the danger zone into margins based on velocity, and ensure it doesn't exceed - // page bounds. - RectF dangerMargins = velocityBiasedMargins(dangerZoneX, dangerZoneY, velocity); - dangerMargins = shiftMarginsForPageBounds(dangerMargins, metrics); - - // we're about to checkerboard if the current viewport area + the danger zone margins - // fall out of the current displayport anywhere. - RectF adjustedViewport = new RectF( - metrics.viewportRectLeft - dangerMargins.left, - metrics.viewportRectTop - dangerMargins.top, - metrics.viewportRectRight + dangerMargins.right, - metrics.viewportRectBottom + dangerMargins.bottom); - return !displayPort.contains(adjustedViewport); - } - - @Override - public String toString() { - return "VelocityBiasStrategy mult=" + SIZE_MULTIPLIER + ", threshold=" + VELOCITY_THRESHOLD + ", reverse=" + REVERSE_BUFFER - + ", dangerBaseX=" + DANGER_ZONE_BASE_X_MULTIPLIER + ", dangerBaseY=" + DANGER_ZONE_BASE_Y_MULTIPLIER - + ", dangerIncrX=" + DANGER_ZONE_INCR_Y_MULTIPLIER + ", dangerIncrY=" + DANGER_ZONE_INCR_Y_MULTIPLIER; - } - } - - /** - * This class implements the variation where we draw more of the page at low resolution while panning. - * In this variation, as we pan faster, we increase the page area we are drawing, but reduce the draw - * resolution to compensate. This results in the same device-pixel area drawn; the compositor then - * scales this up to the viewport zoom level. This results in a large area of the page drawn but it - * looks blurry. The assumption is that drawing extra that we never display is better than checkerboarding, - * where we draw less but never even show it on the screen. - */ - private static class DynamicResolutionStrategy extends DisplayPortStrategy { - // The length of each axis of the display port will be the corresponding view length - // multiplied by this factor. - private static final float SIZE_MULTIPLIER = 1.5f; - - // The velocity above which we start zooming out the display port to keep up - // with the panning. - private static final float VELOCITY_EXPANSION_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() / 16f; - - // How much we increase the display port based on velocity. Assuming no friction and - // splitting (see below), this should be the number of frames (@60fps) between us - // calculating the display port and the draw of the *next* display port getting composited - // and displayed on the screen. This is because the timeline looks like this: - // Java: pan pan pan pan pan pan ! pan pan pan pan pan pan ! - // Gecko: \-> draw -> composite / \-> draw -> composite / - // The display port calculated on the first "pan" gets composited to the screen at the - // first exclamation mark, and remains on the screen until the second exclamation mark. - // In order to avoid checkerboarding, that display port must be able to contain all of - // the panning until the second exclamation mark, which encompasses two entire draw/composite - // cycles. - // If we take into account friction, our velocity multiplier should be reduced as the - // amount of pan will decrease each time. If we take into account display port splitting, - // it should be increased as the splitting means some of the display port will be used to - // draw in the opposite direction of the velocity. For now I'm assuming these two cancel - // each other out. - private static final float VELOCITY_MULTIPLIER = 60.0f; - - // The following constants adjust how biased the display port is in the direction of panning. - // When panning fast (above the FAST_THRESHOLD) we use the fast split factor to split the - // display port "buffer" area, otherwise we use the slow split factor. This is based on the - // assumption that if the user is panning fast, they are less likely to reverse directions - // and go backwards, so we should spend more of our display port buffer in the direction of - // panning. - private static final float VELOCITY_FAST_THRESHOLD = VELOCITY_EXPANSION_THRESHOLD * 2.0f; - private static final float FAST_SPLIT_FACTOR = 0.95f; - private static final float SLOW_SPLIT_FACTOR = 0.8f; - - // The following constants are used for viewport prediction; we use them to estimate where - // the viewport will be soon and whether or not we should trigger a draw right now. "soon" - // in the previous sentence really refers to the amount of time it would take to draw and - // composite from the point at which we do the calculation, and that is not really a known - // quantity. The velocity multiplier is how much we multiply the velocity by; it has the - // same caveats as the VELOCITY_MULTIPLIER above except that it only needs to take into account - // one draw/composite cycle instead of two. The danger zone multiplier is a multiplier of the - // viewport size that we use as an extra "danger zone" around the viewport; if this danger - // zone falls outside the display port then we are approaching the point at which we will - // checkerboard, and hence should start drawing. Note that if DANGER_ZONE_MULTIPLIER is - // greater than (SIZE_MULTIPLIER - 1.0f), then at zero velocity we will always be in the - // danger zone, and thus will be constantly drawing. - private static final float PREDICTION_VELOCITY_MULTIPLIER = 30.0f; - private static final float DANGER_ZONE_MULTIPLIER = 0.20f; // must be less than (SIZE_MULTIPLIER - 1.0f) - - DynamicResolutionStrategy(Map prefs) { - // ignore prefs for now - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float displayPortWidth = metrics.getWidth() * SIZE_MULTIPLIER; - float displayPortHeight = metrics.getHeight() * SIZE_MULTIPLIER; - - // for resolution calculation purposes, we need to know what the adjusted display port dimensions - // would be if we had zero velocity, so calculate that here before we increase the display port - // based on velocity. - FloatSize reshapedSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - - // increase displayPortWidth and displayPortHeight based on the velocity, but maintaining their - // relative aspect ratio. - if (velocity.length() > VELOCITY_EXPANSION_THRESHOLD) { - float velocityFactor = Math.max(Math.abs(velocity.x) / displayPortWidth, - Math.abs(velocity.y) / displayPortHeight); - velocityFactor *= VELOCITY_MULTIPLIER; - - displayPortWidth += (displayPortWidth * velocityFactor); - displayPortHeight += (displayPortHeight * velocityFactor); - } - - // at this point, displayPortWidth and displayPortHeight are how much of the page (in device pixels) - // we want to be rendered by Gecko. Note here "device pixels" is equivalent to CSS pixels multiplied - // by metrics.zoomFactor - - // we need to avoid having a display port that is larger than the page, or we will end up - // painting things outside the page bounds (bug 729169). we simultaneously need to make - // the display port as large as possible so that we redraw less. reshape the display - // port dimensions to accomplish this. this may change the aspect ratio of the display port, - // but we are assuming that this is desirable because the advantages from pre-drawing will - // outweigh the disadvantages from any buffer reallocations that might occur. - FloatSize usableSize = reshapeForPage(displayPortWidth, displayPortHeight, metrics); - float horizontalBuffer = usableSize.width - metrics.getWidth(); - float verticalBuffer = usableSize.height - metrics.getHeight(); - - // at this point, horizontalBuffer and verticalBuffer are the dimensions of the buffer area we have. - // the buffer area is the off-screen area that is part of the display port and will be pre-drawn in case - // the user scrolls there. we now need to split the buffer area on each axis so that we know - // what the exact margins on each side will be. first we split the buffer amount based on the direction - // we're moving, so that we have a larger buffer in the direction of travel. - RectF margins = new RectF(); - margins.left = splitBufferByVelocity(horizontalBuffer, velocity.x); - margins.right = horizontalBuffer - margins.left; - margins.top = splitBufferByVelocity(verticalBuffer, velocity.y); - margins.bottom = verticalBuffer - margins.top; - - // then, we account for running into the page bounds - so that if we hit the top of the page, we need - // to drop the top margin and move that amount to the bottom margin. - margins = shiftMarginsForPageBounds(margins, metrics); - - // finally, we calculate the resolution we want to render the display port area at. We do this - // so that as we expand the display port area (because of velocity), we reduce the resolution of - // the painted area so as to maintain the size of the buffer Gecko is painting into. we calculate - // the reduction in resolution by comparing the display port size with and without the velocity - // changes applied. - // this effectively means that as we pan faster and faster, the display port grows, but we paint - // at lower resolutions. this paints more area to reduce checkerboard at the cost of increasing - // compositor-scaling and blurriness. Once we stop panning, the blurriness must be entirely gone. - // Note that usable* could be less than base* if we are pinch-zoomed out into overscroll, so we - // clamp it to make sure this doesn't increase our display resolution past metrics.zoomFactor. - float scaleFactor = Math.min(reshapedSize.width / usableSize.width, reshapedSize.height / usableSize.height); - float displayResolution = metrics.zoomFactor * Math.min(1.0f, scaleFactor); - - DisplayPortMetrics dpMetrics = new DisplayPortMetrics( - metrics.viewportRectLeft - margins.left, - metrics.viewportRectTop - margins.top, - metrics.viewportRectRight + margins.right, - metrics.viewportRectBottom + margins.bottom, - displayResolution); - return dpMetrics; - } - - /** - * Split the given buffer amount into two based on the velocity. - * Given an amount of total usable buffer on an axis, this will - * return the amount that should be used on the left/top side of - * the axis (the side which a negative velocity vector corresponds - * to). - */ - private float splitBufferByVelocity(float amount, float velocity) { - // if no velocity, so split evenly - if (FloatUtils.fuzzyEquals(velocity, 0)) { - return amount / 2.0f; - } - // if we're moving quickly, assign more of the amount in that direction - // since is is less likely that we will reverse direction immediately - if (velocity < -VELOCITY_FAST_THRESHOLD) { - return amount * FAST_SPLIT_FACTOR; - } - if (velocity > VELOCITY_FAST_THRESHOLD) { - return amount * (1.0f - FAST_SPLIT_FACTOR); - } - // if we're moving slowly, then assign less of the amount in that direction - if (velocity < 0) { - return amount * SLOW_SPLIT_FACTOR; - } else { - return amount * (1.0f - SLOW_SPLIT_FACTOR); - } - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // Expand the viewport based on our velocity (and clamp it to page boundaries). - // Then intersect it with the last-requested displayport to determine whether we're - // close to checkerboarding. - - RectF predictedViewport = metrics.getViewport(); - - // first we expand the viewport in the direction we're moving based on some - // multiple of the current velocity. - if (velocity.length() > 0) { - if (velocity.x < 0) { - predictedViewport.left += velocity.x * PREDICTION_VELOCITY_MULTIPLIER; - } else if (velocity.x > 0) { - predictedViewport.right += velocity.x * PREDICTION_VELOCITY_MULTIPLIER; - } - - if (velocity.y < 0) { - predictedViewport.top += velocity.y * PREDICTION_VELOCITY_MULTIPLIER; - } else if (velocity.y > 0) { - predictedViewport.bottom += velocity.y * PREDICTION_VELOCITY_MULTIPLIER; - } - } - - // then we expand the viewport evenly in all directions just to have an extra - // safety zone. this also clamps it to page bounds. - predictedViewport = expandByDangerZone(predictedViewport, DANGER_ZONE_MULTIPLIER, DANGER_ZONE_MULTIPLIER, metrics); - return !displayPort.contains(predictedViewport); - } - - @Override - public String toString() { - return "DynamicResolutionStrategy"; - } - } - - /** - * This class implements the variation where we use the draw time to predict where we will be when - * a draw completes, and draw that instead of where we are now. In this variation, when our panning - * speed drops below a certain threshold, we draw 9 viewports' worth of content so that the user can - * pan in any direction without encountering checkerboarding. - * Once the user is panning, we modify the displayport to encompass an area range of where we think - * the user will be when the draw completes. This heuristic relies on both the estimated draw time - * the panning velocity; unexpected changes in either of these values will cause the heuristic to - * fail and show checkerboard. - */ - private static class PredictionBiasStrategy extends DisplayPortStrategy { - private static float VELOCITY_THRESHOLD; - - private int mPixelArea; // area of the viewport, used in draw time calculations - private int mMinFramesToDraw; // minimum number of frames we take to draw - private int mMaxFramesToDraw; // maximum number of frames we take to draw - - PredictionBiasStrategy(Map prefs) { - VELOCITY_THRESHOLD = /*GeckoAppShell.getDpi()*/ LOKitShell.getDpi() * getFloatPref(prefs, PREF_DISPLAYPORT_PB_VELOCITY_THRESHOLD, 16); - resetPageState(); - } - - @Override - public DisplayPortMetrics calculate(ImmutableViewportMetrics metrics, PointF velocity) { - float width = metrics.getWidth(); - float height = metrics.getHeight(); - mPixelArea = (int)(width * height); - - if (velocity.length() < VELOCITY_THRESHOLD) { - // if we're going slow, expand the displayport to 9x viewport size - RectF margins = new RectF(width, height, width, height); - return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - // figure out how far we expect to be - float minDx = velocity.x * mMinFramesToDraw; - float minDy = velocity.y * mMinFramesToDraw; - float maxDx = velocity.x * mMaxFramesToDraw; - float maxDy = velocity.y * mMaxFramesToDraw; - - // figure out how many pixels we will be drawing when we draw the above-calculated range. - // this will be larger than the viewport area. - float pixelsToDraw = (width + Math.abs(maxDx - minDx)) * (height + Math.abs(maxDy - minDy)); - // adjust how far we will get because of the time spent drawing all these extra pixels. this - // will again increase the number of pixels drawn so really we could keep iterating this over - // and over, but once seems enough for now. - maxDx = maxDx * pixelsToDraw / mPixelArea; - maxDy = maxDy * pixelsToDraw / mPixelArea; - - // and finally generate the displayport. the min/max stuff takes care of - // negative velocities as well as positive. - RectF margins = new RectF( - -Math.min(minDx, maxDx), - -Math.min(minDy, maxDy), - Math.max(minDx, maxDx), - Math.max(minDy, maxDy)); - return getTileAlignedDisplayPortMetrics(margins, metrics.zoomFactor, metrics); - } - - @Override - public boolean aboutToCheckerboard(ImmutableViewportMetrics metrics, PointF velocity, DisplayPortMetrics displayPort) { - // the code below is the same as in calculate() but is awkward to refactor since it has multiple outputs. - // refer to the comments in calculate() to understand what this is doing. - float minDx = velocity.x * mMinFramesToDraw; - float minDy = velocity.y * mMinFramesToDraw; - float maxDx = velocity.x * mMaxFramesToDraw; - float maxDy = velocity.y * mMaxFramesToDraw; - float pixelsToDraw = (metrics.getWidth() + Math.abs(maxDx - minDx)) * (metrics.getHeight() + Math.abs(maxDy - minDy)); - maxDx = maxDx * pixelsToDraw / mPixelArea; - maxDy = maxDy * pixelsToDraw / mPixelArea; - - // now that we have an idea of how far we will be when the draw completes, take the farthest - // end of that range and see if it falls outside the displayport bounds. if it does, allow - // the draw to go through - RectF predictedViewport = metrics.getViewport(); - predictedViewport.left += maxDx; - predictedViewport.top += maxDy; - predictedViewport.right += maxDx; - predictedViewport.bottom += maxDy; - - predictedViewport = clampToPageBounds(predictedViewport, metrics); - return !displayPort.contains(predictedViewport); - } - - @Override - public boolean drawTimeUpdate(long millis, int pixels) { - // calculate the number of frames it took to draw a viewport-sized area - float normalizedTime = (float)mPixelArea * (float)millis / (float)pixels; - int normalizedFrames = (int)FloatMath.ceil(normalizedTime * 60f / 1000f); - // broaden our range on how long it takes to draw if the draw falls outside - // the range. this allows it to grow gradually. this heuristic may need to - // be tweaked into more of a floating window average or something. - if (normalizedFrames <= mMinFramesToDraw) { - mMinFramesToDraw--; - } else if (normalizedFrames > mMaxFramesToDraw) { - mMaxFramesToDraw++; - } else { - return true; - } - Log.d(LOGTAG, "Widened draw range to [" + mMinFramesToDraw + ", " + mMaxFramesToDraw + "]"); - return true; - } - - @Override - public void resetPageState() { - mMinFramesToDraw = 0; - mMaxFramesToDraw = 2; - } - - @Override - public String toString() { - return "PredictionBiasStrategy threshold=" + VELOCITY_THRESHOLD; - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java deleted file mode 100644 index 741136f90a53..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DisplayPortMetrics.java +++ /dev/null @@ -1,78 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -import org.mozilla.gecko.util.FloatUtils; - -import android.graphics.RectF; - -/* - * This class keeps track of the area we request Gecko to paint, as well - * as the resolution of the paint. The area may be different from the visible - * area of the page, and the resolution may be different from the resolution - * used in the compositor to render the page. This is so that we can ask Gecko - * to paint a much larger area without using extra memory, and then render some - * subsection of that with compositor scaling. - */ -public final class DisplayPortMetrics { - //@WrapElementForJNI - public final float resolution; - //@WrapElementForJNI - private final RectF mPosition; - - public DisplayPortMetrics() { - this(0, 0, 0, 0, 1); - } - - //@WrapElementForJNI - public DisplayPortMetrics(float left, float top, float right, float bottom, float resolution) { - this.resolution = resolution; - mPosition = new RectF(left, top, right, bottom); - } - - public float getLeft() { - return mPosition.left; - } - - public float getTop() { - return mPosition.top; - } - - public float getRight() { - return mPosition.right; - } - - public float getBottom() { - return mPosition.bottom; - } - - public boolean contains(RectF rect) { - return mPosition.contains(rect); - } - - public boolean fuzzyEquals(DisplayPortMetrics metrics) { - return RectUtils.fuzzyEquals(mPosition, metrics.mPosition) - && FloatUtils.fuzzyEquals(resolution, metrics.resolution); - } - - public String toJSON() { - StringBuilder sb = new StringBuilder(256); - sb.append("{ \"left\": ").append(mPosition.left) - .append(", \"top\": ").append(mPosition.top) - .append(", \"right\": ").append(mPosition.right) - .append(", \"bottom\": ").append(mPosition.bottom) - .append(", \"resolution\": ").append(resolution) - .append('}'); - return sb.toString(); - } - - @Override - public String toString() { - return "DisplayPortMetrics v=(" + mPosition.left + "," + mPosition.top + "," + mPosition.right + "," - + mPosition.bottom + ") z=" + resolution; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java deleted file mode 100644 index ce868f18ce2f..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/DrawTimingQueue.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.os.SystemClock; - -/** - * A custom-built data structure to assist with measuring draw times. - * - * This class maintains a fixed-size circular buffer of DisplayPortMetrics - * objects and associated timestamps. It provides only three operations, which - * is all we require for our purposes of measuring draw times. Note - * in particular that the class is designed so that even though it is - * accessed from multiple threads, it does not require synchronization; - * any concurrency errors that result from this are handled gracefully. - * - * Assuming an unrolled buffer so that mTail is greater than mHead, the data - * stored in the buffer at entries [mHead, mTail) will never be modified, and - * so are "safe" to read. If this reading is done on the same thread that - * owns mHead, then reading the range [mHead, mTail) is guaranteed to be safe - * since the range itself will not shrink. - */ -final class DrawTimingQueue { - private static final String LOGTAG = "GeckoDrawTimingQueue"; - private static final int BUFFER_SIZE = 16; - - private final DisplayPortMetrics[] mMetrics; - private final long[] mTimestamps; - - private int mHead; - private int mTail; - - DrawTimingQueue() { - mMetrics = new DisplayPortMetrics[BUFFER_SIZE]; - mTimestamps = new long[BUFFER_SIZE]; - mHead = BUFFER_SIZE - 1; - mTail = 0; - } - - /** - * Add a new entry to the tail of the queue. If the buffer is full, - * do nothing. This must only be called from the Java UI thread. - */ - boolean add(DisplayPortMetrics metrics) { - if (mHead == mTail) { - return false; - } - mMetrics[mTail] = metrics; - mTimestamps[mTail] = SystemClock.uptimeMillis(); - mTail = (mTail + 1) % BUFFER_SIZE; - return true; - } - - /** - * Find the timestamp associated with the given metrics, AND remove - * all metrics objects from the start of the queue up to and including - * the one provided. Note that because of draw coalescing, the metrics - * object passed in here may not be the one at the head of the queue, - * and so we must iterate our way through the list to find it. - * This must only be called from the compositor thread. - */ - long findTimeFor(DisplayPortMetrics metrics) { - // keep a copy of the tail pointer so that we ignore new items - // added to the queue while we are searching. this is fine because - // the one we are looking for will either have been added already - // or will not be in the queue at all. - int tail = mTail; - // walk through the "safe" range from mHead to tail; these entries - // will not be modified unless we change mHead. - int i = (mHead + 1) % BUFFER_SIZE; - while (i != tail) { - if (mMetrics[i].fuzzyEquals(metrics)) { - // found it, copy out the timestamp to a local var BEFORE - // changing mHead or add could clobber the timestamp. - long timestamp = mTimestamps[i]; - mHead = i; - return timestamp; - } - i = (i + 1) % BUFFER_SIZE; - } - return -1; - } - - /** - * Reset the buffer to empty. - * This must only be called from the compositor thread. - */ - void reset() { - // we can only modify mHead on this thread. - mHead = (mTail + BUFFER_SIZE - 1) % BUFFER_SIZE; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java deleted file mode 100644 index 4b495ab77ecc..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java +++ /dev/null @@ -1,54 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.FloatUtils; - -import org.json.JSONException; -import org.json.JSONObject; - -public class FloatSize { - public final float width, height; - - public FloatSize(FloatSize size) { width = size.width; height = size.height; } - public FloatSize(IntSize size) { width = size.width; height = size.height; } - public FloatSize(float aWidth, float aHeight) { width = aWidth; height = aHeight; } - - public FloatSize(JSONObject json) { - try { - width = (float)json.getDouble("width"); - height = (float)json.getDouble("height"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { return "(" + width + "," + height + ")"; } - - public boolean isPositive() { - return (width > 0 && height > 0); - } - - public boolean fuzzyEquals(FloatSize size) { - return (FloatUtils.fuzzyEquals(size.width, width) && - FloatUtils.fuzzyEquals(size.height, height)); - } - - public FloatSize scale(float factor) { - return new FloatSize(width * factor, height * factor); - } - - /* - * Returns the size that represents a linear transition between this size and `to` at time `t`, - * which is on the scale [0, 1). - */ - public FloatSize interpolate(FloatSize to, float t) { - return new FloatSize(FloatUtils.interpolate(width, to.width, t), - FloatUtils.interpolate(height, to.height, t)); - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java deleted file mode 100644 index be6118894e6a..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GLController.java +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -//import org.mozilla.gecko.GeckoThread; -//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.util.ThreadUtils; - -import android.util.Log; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -/** - * EGLPreloadingThread is purely a preloading optimization, not something - * we rely on for anything else than performance. We will be initializing - * EGL in GLController::initEGL() when we need it, but having EGL initialization - * already previously done by EGLPreloadingThread::run() will make it much - * faster for GLController to do again. - * - * For example, here are some timings recorded on two devices: - * - * Device | EGLPreloadingThread::run() | GLController::initEGL() - * -----------------------+----------------------------+------------------------ - * Nexus S (Android 2.3) | ~ 80 ms | < 0.1 ms - * Nexus 10 (Android 4.3) | ~ 35 ms | < 0.1 ms - */ -class EGLPreloadingThread extends Thread -{ - private static final String LOGTAG = "EGLPreloadingThread"; - private EGL10 mEGL; - private EGLDisplay mEGLDisplay; - - public EGLPreloadingThread() - { - } - - @Override - public void run() - { - mEGL = (EGL10)EGLContext.getEGL(); - mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) { - Log.w(LOGTAG, "Can't get EGL display!"); - return; - } - - int[] returnedVersion = new int[2]; - if (!mEGL.eglInitialize(mEGLDisplay, returnedVersion)) { - Log.w(LOGTAG, "eglInitialize failed"); - return; - } - } -} - -/** - * This class is a singleton that tracks EGL and compositor things over - * the lifetime of Fennec running. - * We only ever create one C++ compositor over Fennec's lifetime, but - * most of the Java-side objects (e.g. LayerView, GeckoLayerClient, - * LayerRenderer) can all get destroyed and re-created if the GeckoApp - * activity is destroyed. This GLController is never destroyed, so that - * the mCompositorCreated field and other state variables are always - * accurate. - */ -public class GLController { - private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - private static final String LOGTAG = "GeckoGLController"; - - private static GLController sInstance; - - private LayerView mView; - private boolean mServerSurfaceValid; - private int mWidth, mHeight; - - /* This is written by the compositor thread (while the UI thread - * is blocked on it) and read by the UI thread. */ - private volatile boolean mCompositorCreated; - - private EGL10 mEGL; - private EGLDisplay mEGLDisplay; - private EGLConfig mEGLConfig; - private EGLPreloadingThread mEGLPreloadingThread; - private EGLSurface mEGLSurfaceForCompositor; - - private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4; - - private static final int[] CONFIG_SPEC_16BPP = { - EGL10.EGL_RED_SIZE, 5, - EGL10.EGL_GREEN_SIZE, 6, - EGL10.EGL_BLUE_SIZE, 5, - EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, - EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT, - EGL10.EGL_NONE - }; - - private static final int[] CONFIG_SPEC_24BPP = { - EGL10.EGL_RED_SIZE, 8, - EGL10.EGL_GREEN_SIZE, 8, - EGL10.EGL_BLUE_SIZE, 8, - EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, - EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT, - EGL10.EGL_NONE - }; - - private GLController() { - mEGLPreloadingThread = new EGLPreloadingThread(); - mEGLPreloadingThread.start(); - } - - static GLController getInstance(LayerView view) { - if (sInstance == null) { - sInstance = new GLController(); - } - sInstance.mView = view; - return sInstance; - } - - synchronized void serverSurfaceDestroyed() { - ThreadUtils.assertOnUiThread(); - Log.w(LOGTAG, "GLController::serverSurfaceDestroyed() with mCompositorCreated=" + mCompositorCreated); - - mServerSurfaceValid = false; - - if (mEGLSurfaceForCompositor != null) { - mEGL.eglDestroySurface(mEGLDisplay, mEGLSurfaceForCompositor); - mEGLSurfaceForCompositor = null; - } - - // We need to coordinate with Gecko when pausing composition, to ensure - // that Gecko never executes a draw event while the compositor is paused. - // This is sent synchronously to make sure that we don't attempt to use - // any outstanding Surfaces after we call this (such as from a - // serverSurfaceDestroyed notification), and to make sure that any in-flight - // Gecko draw events have been processed. When this returns, composition is - // definitely paused -- it'll synchronize with the Gecko event loop, which - // in turn will synchronize with the compositor thread. - if (mCompositorCreated) { - //GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorPauseEvent()); - } - Log.w(LOGTAG, "done GLController::serverSurfaceDestroyed()"); - } - - synchronized void serverSurfaceChanged(int newWidth, int newHeight) { - ThreadUtils.assertOnUiThread(); - Log.w(LOGTAG, "GLController::serverSurfaceChanged(" + newWidth + ", " + newHeight + ")"); - - mWidth = newWidth; - mHeight = newHeight; - mServerSurfaceValid = true; - - // we defer to a runnable the task of updating the compositor, because this is going to - // call back into createEGLSurfaceForCompositor, which will try to create an EGLSurface - // against mView, which we suspect might fail if called too early. By posting this to - // mView, we hope to ensure that it is deferred until mView is actually "ready" for some - // sense of "ready". - mView.post(new Runnable() { - @Override - public void run() { - updateCompositor(); - } - }); - } - - void updateCompositor() { - ThreadUtils.assertOnUiThread(); - Log.w(LOGTAG, "GLController::updateCompositor with mCompositorCreated=" + mCompositorCreated); - - if (mCompositorCreated) { - // If the compositor has already been created, just resume it instead. We don't need - // to block here because if the surface is destroyed before the compositor grabs it, - // we can handle that gracefully (i.e. the compositor will remain paused). - resumeCompositor(mWidth, mHeight); - Log.w(LOGTAG, "done GLController::updateCompositor with compositor resume"); - return; - } - - if (!AttemptPreallocateEGLSurfaceForCompositor()) { - return; - } - - // Only try to create the compositor if we have a valid surface and gecko is up. When these - // two conditions are satisfied, we can be relatively sure that the compositor creation will - // happen without needing to block anywhere. Do it with a sync gecko event so that the - // android doesn't have a chance to destroy our surface in between. - /*if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { - GeckoAppShell.sendEventToGeckoSync(GeckoEvent.createCompositorCreateEvent(mWidth, mHeight)); - }*/ - Log.w(LOGTAG, "done GLController::updateCompositor"); - } - - void compositorCreated() { - Log.w(LOGTAG, "GLController::compositorCreated"); - // This is invoked on the compositor thread, while the java UI thread - // is blocked on the gecko sync event in updateCompositor() above - mCompositorCreated = true; - } - - public boolean isServerSurfaceValid() { - return mServerSurfaceValid; - } - - public boolean isCompositorCreated() { - return mCompositorCreated; - } - - private void initEGL() { - if (mEGL != null) { - return; - } - - // This join() should not be necessary, but makes this code a bit easier to think about. - // The EGLPreloadingThread should long be done by now, and even if it's not, - // it shouldn't be a problem to be initalizing EGL from two different threads. - // Still, having this join() here means that we don't have to wonder about what - // kind of caveats might exist with EGL initialization reentrancy on various drivers. - try { - mEGLPreloadingThread.join(); - } catch (InterruptedException e) { - Log.w(LOGTAG, "EGLPreloadingThread interrupted", e); - } - - mEGL = (EGL10)EGLContext.getEGL(); - - mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) { - Log.w(LOGTAG, "Can't get EGL display!"); - return; - } - - // while calling eglInitialize here should not be necessary as it was already called - // by the EGLPreloadingThread, it really doesn't cost much to call it again here, - // and makes this code easier to think about: EGLPreloadingThread is only a - // preloading optimization, not something we rely on for anything else. - // - // Also note that while calling eglInitialize isn't necessary on Android 4.x - // (at least Android's HardwareRenderer does it for us already), it is necessary - // on Android 2.x. - int[] returnedVersion = new int[2]; - if (!mEGL.eglInitialize(mEGLDisplay, returnedVersion)) { - Log.w(LOGTAG, "eglInitialize failed"); - return; - } - - mEGLConfig = chooseConfig(); - } - - private EGLConfig chooseConfig() { - int[] desiredConfig; - int rSize, gSize, bSize; - int[] numConfigs = new int[1]; - - switch (/*GeckoAppShell*/LOKitShell.getScreenDepth()) { - case 24: - desiredConfig = CONFIG_SPEC_24BPP; - rSize = gSize = bSize = 8; - break; - case 16: - default: - desiredConfig = CONFIG_SPEC_16BPP; - rSize = 5; gSize = 6; bSize = 5; - break; - } - - if (!mEGL.eglChooseConfig(mEGLDisplay, desiredConfig, null, 0, numConfigs) || - numConfigs[0] <= 0) { - throw new GLControllerException("No available EGL configurations " + - getEGLError()); - } - - EGLConfig[] configs = new EGLConfig[numConfigs[0]]; - if (!mEGL.eglChooseConfig(mEGLDisplay, desiredConfig, configs, numConfigs[0], numConfigs)) { - throw new GLControllerException("No EGL configuration for that specification " + - getEGLError()); - } - - // Select the first configuration that matches the screen depth. - int[] red = new int[1], green = new int[1], blue = new int[1]; - for (EGLConfig config : configs) { - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red); - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green); - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue); - if (red[0] == rSize && green[0] == gSize && blue[0] == bSize) { - return config; - } - } - - throw new GLControllerException("No suitable EGL configuration found"); - } - - private synchronized boolean AttemptPreallocateEGLSurfaceForCompositor() { - if (mEGLSurfaceForCompositor == null) { - initEGL(); - try { - mEGLSurfaceForCompositor = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mView.getNativeWindow(), null); - // In failure cases, eglCreateWindowSurface should return EGL_NO_SURFACE. - // We currently normalize this to null, and compare to null in all our checks. - if (mEGLSurfaceForCompositor == EGL10.EGL_NO_SURFACE) { - mEGLSurfaceForCompositor = null; - } - } catch (Exception e) { - Log.e(LOGTAG, "eglCreateWindowSurface threw", e); - } - } - if (mEGLSurfaceForCompositor == null) { - Log.w(LOGTAG, "eglCreateWindowSurface returned no surface!"); - } - return mEGLSurfaceForCompositor != null; - } - - // @WrapElementForJNI(allowMultithread = true, stubName = "CreateEGLSurfaceForCompositorWrapper") - private synchronized EGLSurface createEGLSurfaceForCompositor() { - AttemptPreallocateEGLSurfaceForCompositor(); - EGLSurface result = mEGLSurfaceForCompositor; - mEGLSurfaceForCompositor = null; - return result; - } - - private String getEGLError() { - return "Error " + (mEGL == null ? "(no mEGL)" : mEGL.eglGetError()); - } - - void resumeCompositor(int width, int height) { - Log.w(LOGTAG, "GLController::resumeCompositor(" + width + ", " + height + ") and mCompositorCreated=" + mCompositorCreated); - // Asking Gecko to resume the compositor takes too long (see - // https://bugzilla.mozilla.org/show_bug.cgi?id=735230#c23), so we - // resume the compositor directly. We still need to inform Gecko about - // the compositor resuming, so that Gecko knows that it can now draw. - // It is important to not notify Gecko until after the compositor has - // been resumed, otherwise Gecko may send updates that get dropped. - if (mCompositorCreated) { - //GeckoAppShell.scheduleResumeComposition(width, height); - //GeckoAppShell.sendEventToGecko(GeckoEvent.createCompositorResumeEvent()); - } - Log.w(LOGTAG, "done GLController::resumeCompositor"); - } - - public static class GLControllerException extends RuntimeException { - public static final long serialVersionUID = 1L; - - GLControllerException(String e) { - super(e); - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java deleted file mode 100644 index 049b1fe59564..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ /dev/null @@ -1,1000 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -//import org.mozilla.gecko.Tab; -//import org.mozilla.gecko.Tabs; -import org.mozilla.gecko.ZoomConstraints; -//import org.mozilla.gecko.mozglue.RobocopTarget; -//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -import org.mozilla.gecko.util.EventDispatcher; -import org.mozilla.gecko.util.FloatUtils; - -import android.content.Context; -import android.graphics.PointF; -import android.graphics.RectF; -import android.os.SystemClock; -import android.util.DisplayMetrics; -import android.util.Log; - -public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget -{ - private static final String LOGTAG = "GeckoLayerClient"; - - private LayerRenderer mLayerRenderer; - private boolean mLayerRendererInitialized; - - private Context mContext; - private IntSize mScreenSize; - private IntSize mWindowSize; - private DisplayPortMetrics mDisplayPort; - - private boolean mRecordDrawTimes; - private final DrawTimingQueue mDrawTimingQueue; - - private VirtualLayer mRootLayer; - - /* The Gecko viewport as per the UI thread. Must be touched only on the UI thread. - * If any events being sent to Gecko that are relative to the Gecko viewport position, - * they must (a) be relative to this viewport, and (b) be sent on the UI thread to - * avoid races. As long as these two conditions are satisfied, and the events being - * sent to Gecko are processed in FIFO order, the events will properly be relative - * to the Gecko viewport position. Note that if Gecko updates its viewport independently, - * we get notified synchronously and also update this on the UI thread. - */ - private ImmutableViewportMetrics mGeckoViewport; - - /* - * The viewport metrics being used to draw the current frame. This is only - * accessed by the compositor thread, and so needs no synchronisation. - */ - private ImmutableViewportMetrics mFrameMetrics; - - private DrawListener mDrawListener; - - /* Used as temporaries by syncViewportInfo */ - private final ViewTransform mCurrentViewTransform; - private final RectF mCurrentViewTransformMargins; - - /* Used as the return value of progressiveUpdateCallback */ - private final ProgressiveUpdateData mProgressiveUpdateData; - private DisplayPortMetrics mProgressiveUpdateDisplayPort; - private boolean mLastProgressiveUpdateWasLowPrecision; - private boolean mProgressiveUpdateWasInDanger; - - private boolean mForceRedraw; - - /* The current viewport metrics. - * This is volatile so that we can read and write to it from different threads. - * We avoid synchronization to make getting the viewport metrics from - * the compositor as cheap as possible. The viewport is immutable so - * we don't need to worry about anyone mutating it while we're reading from it. - * Specifically: - * 1) reading mViewportMetrics from any thread is fine without synchronization - * 2) writing to mViewportMetrics requires synchronizing on the layer controller object - * 3) whenver reading multiple fields from mViewportMetrics without synchronization (i.e. in - * case 1 above) you should always frist grab a local copy of the reference, and then use - * that because mViewportMetrics might get reassigned in between reading the different - * fields. */ - private volatile ImmutableViewportMetrics mViewportMetrics; - private OnMetricsChangedListener mViewportChangeListener; - - private ZoomConstraints mZoomConstraints; - - private boolean mGeckoIsReady; - - private final PanZoomController mPanZoomController; - private final LayerMarginsAnimator mMarginsAnimator; - private LayerView mView; - - /* This flag is true from the time that browser.js detects a first-paint is about to start, - * to the time that we receive the first-paint composite notification from the compositor. - * Note that there is a small race condition with this; if there are two paints that both - * have the first-paint flag set, and the second paint happens concurrently with the - * composite for the first paint, then this flag may be set to true prematurely. Fixing this - * is possible but risky; see https://bugzilla.mozilla.org/show_bug.cgi?id=797615#c751 - */ - private volatile boolean mContentDocumentIsDisplayed; - - public GeckoLayerClient(Context context, LayerView view, EventDispatcher eventDispatcher) { - // we can fill these in with dummy values because they are always written - // to before being read - mContext = context; - mScreenSize = new IntSize(0, 0); - mWindowSize = new IntSize(0, 0); - mDisplayPort = new DisplayPortMetrics(); - mRecordDrawTimes = true; - mDrawTimingQueue = new DrawTimingQueue(); - mCurrentViewTransform = new ViewTransform(0, 0, 1); - mCurrentViewTransformMargins = new RectF(); - mProgressiveUpdateData = new ProgressiveUpdateData(); - mProgressiveUpdateDisplayPort = new DisplayPortMetrics(); - mLastProgressiveUpdateWasLowPrecision = false; - mProgressiveUpdateWasInDanger = false; - - mForceRedraw = true; - DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); - mViewportMetrics = new ImmutableViewportMetrics(displayMetrics) - .setViewportSize(view.getWidth(), view.getHeight()); - mZoomConstraints = new ZoomConstraints(false); - - /*Tab tab = Tabs.getInstance().getSelectedTab(); - if (tab != null) { - mZoomConstraints = tab.getZoomConstraints(); - mViewportMetrics = mViewportMetrics.setIsRTL(tab.getIsRTL()); - }*/ - - mFrameMetrics = mViewportMetrics; - - mPanZoomController = PanZoomController.Factory.create(this, view, eventDispatcher); - mMarginsAnimator = new LayerMarginsAnimator(this, view); - mView = view; - mView.setListener(this); - mContentDocumentIsDisplayed = true; - } - - public void setOverscrollHandler(final Overscroll listener) { - mPanZoomController.setOverscrollHandler(listener); - } - - /** Attaches to root layer so that Gecko appears. */ - public void notifyGeckoReady() { - mGeckoIsReady = true; - - mRootLayer = new VirtualLayer(new IntSize(mView.getWidth(), mView.getHeight())); - mLayerRenderer = mView.getRenderer(); - - sendResizeEventIfNecessary(true); - - DisplayPortCalculator.initPrefs(); - - // Gecko being ready is one of the two conditions (along with having an available - // surface) that cause us to create the compositor. So here, now that we know gecko - // is ready, call updateCompositor() to see if we can actually do the creation. - // This needs to run on the UI thread so that the surface validity can't change on - // us while we're in the middle of creating the compositor. - mView.post(new Runnable() { - @Override - public void run() { - mView.getGLController().updateCompositor(); - } - }); - } - - public void destroy() { - mPanZoomController.destroy(); - mMarginsAnimator.destroy(); - } - - /** - * Returns true if this client is fine with performing a redraw operation or false if it - * would prefer that the action didn't take place. - */ - private boolean getRedrawHint() { - if (mForceRedraw) { - mForceRedraw = false; - return true; - } - - if (!mPanZoomController.getRedrawHint()) { - return false; - } - - return DisplayPortCalculator.aboutToCheckerboard(mViewportMetrics, - mPanZoomController.getVelocityVector(), mDisplayPort); - } - - Layer getRoot() { - return mGeckoIsReady ? mRootLayer : null; - } - - public LayerView getView() { - return mView; - } - - public FloatSize getViewportSize() { - return mViewportMetrics.getSize(); - } - - /** - * The view calls this function to indicate that the viewport changed size. It must hold the - * monitor while calling it. - * - * TODO: Refactor this to use an interface. Expose that interface only to the view and not - * to the layer client. That way, the layer client won't be tempted to call this, which might - * result in an infinite loop. - */ - void setViewportSize(int width, int height) { - mViewportMetrics = mViewportMetrics.setViewportSize(width, height); - - if (mGeckoIsReady) { - // here we send gecko a resize message. The code in browser.js is responsible for - // picking up on that resize event, modifying the viewport as necessary, and informing - // us of the new viewport. - sendResizeEventIfNecessary(true); - // the following call also sends gecko a message, which will be processed after the resize - // message above has updated the viewport. this message ensures that if we have just put - // focus in a text field, we scroll the content so that the text field is in view. - - //GeckoAppShell.viewSizeChanged(); - } - } - - PanZoomController getPanZoomController() { - return mPanZoomController; - } - - LayerMarginsAnimator getLayerMarginsAnimator() { - return mMarginsAnimator; - } - - /* Informs Gecko that the screen size has changed. */ - private void sendResizeEventIfNecessary(boolean force) { - DisplayMetrics metrics = mContext.getResources().getDisplayMetrics(); - - IntSize newScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); - IntSize newWindowSize = new IntSize(mView.getWidth(), mView.getHeight()); - - boolean screenSizeChanged = !mScreenSize.equals(newScreenSize); - boolean windowSizeChanged = !mWindowSize.equals(newWindowSize); - - if (!force && !screenSizeChanged && !windowSizeChanged) { - return; - } - - mScreenSize = newScreenSize; - mWindowSize = newWindowSize; - - if (screenSizeChanged) { - Log.d(LOGTAG, "Screen-size changed to " + mScreenSize); - } - - if (windowSizeChanged) { - Log.d(LOGTAG, "Window-size changed to " + mWindowSize); - } - - /*GeckoEvent event = GeckoEvent.createSizeChangedEvent(mWindowSize.width, mWindowSize.height, - mScreenSize.width, mScreenSize.height); - GeckoAppShell.sendEventToGecko(event); - GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Window:Resize", ""));*/ - } - - /** Sets the current page rect. You must hold the monitor while calling this. */ - private void setPageRect(RectF rect, RectF cssRect) { - // Since the "rect" is always just a multiple of "cssRect" we don't need to - // check both; this function assumes that both "rect" and "cssRect" are relative - // the zoom factor in mViewportMetrics. - if (mViewportMetrics.getCssPageRect().equals(cssRect)) - return; - - mViewportMetrics = mViewportMetrics.setPageRect(rect, cssRect); - - // Page size is owned by the layer client, so no need to notify it of - // this change. - - post(new Runnable() { - @Override - public void run() { - mPanZoomController.pageRectUpdated(); - mView.requestRender(); - } - }); - } - - /** - * Derives content document fixed position margins/fixed layer margins from - * the view margins in the given metrics object. - */ - private void getFixedMargins(ImmutableViewportMetrics metrics, RectF fixedMargins) { - fixedMargins.left = 0; - fixedMargins.top = 0; - fixedMargins.right = 0; - fixedMargins.bottom = 0; - - // The maximum margins are determined by the scrollable area of the page. - float maxMarginWidth = Math.max(0, metrics.getPageWidth() - metrics.getWidthWithoutMargins()); - float maxMarginHeight = Math.max(0, metrics.getPageHeight() - metrics.getHeightWithoutMargins()); - - // If the margins can't fully hide, they're pinned on - in which case, - // fixed margins should always be zero. - if (maxMarginWidth < metrics.marginLeft + metrics.marginRight) { - maxMarginWidth = 0; - } - if (maxMarginHeight < metrics.marginTop + metrics.marginBottom) { - maxMarginHeight = 0; - } - - PointF offset = metrics.getMarginOffset(); - RectF overscroll = metrics.getOverscroll(); - if (offset.x >= 0) { - fixedMargins.right = Math.max(0, Math.min(offset.x - overscroll.right, maxMarginWidth)); - } else { - fixedMargins.left = Math.max(0, Math.min(-offset.x - overscroll.left, maxMarginWidth)); - } - if (offset.y >= 0) { - fixedMargins.bottom = Math.max(0, Math.min(offset.y - overscroll.bottom, maxMarginHeight)); - } else { - fixedMargins.top = Math.max(0, Math.min(-offset.y - overscroll.top, maxMarginHeight)); - } - - // Adjust for overscroll. If we're overscrolled on one side, add that - // distance to the margins of the other side (limiting to the maximum - // margin size calculated above). - if (overscroll.left > 0) { - fixedMargins.right = Math.min(maxMarginWidth - fixedMargins.left, - fixedMargins.right + overscroll.left); - } else if (overscroll.right > 0) { - fixedMargins.left = Math.min(maxMarginWidth - fixedMargins.right, - fixedMargins.left + overscroll.right); - } - if (overscroll.top > 0) { - fixedMargins.bottom = Math.min(maxMarginHeight - fixedMargins.top, - fixedMargins.bottom + overscroll.top); - } else if (overscroll.bottom > 0) { - fixedMargins.top = Math.min(maxMarginHeight - fixedMargins.bottom, - fixedMargins.top + overscroll.bottom); - } - } - - private void adjustViewport(DisplayPortMetrics displayPort) { - ImmutableViewportMetrics metrics = getViewportMetrics(); - ImmutableViewportMetrics clampedMetrics = metrics.clamp(); - - RectF margins = new RectF(); - getFixedMargins(metrics, margins); - clampedMetrics = clampedMetrics.setMargins( - margins.left, margins.top, margins.right, margins.bottom); - - if (displayPort == null) { - displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector()); - } - - mDisplayPort = displayPort; - mGeckoViewport = clampedMetrics; - - if (mRecordDrawTimes) { - mDrawTimingQueue.add(displayPort); - } - - //GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort)); - } - - /** Aborts any pan/zoom animation that is currently in progress. */ - private void abortPanZoomAnimation() { - if (mPanZoomController != null) { - post(new Runnable() { - @Override - public void run() { - mPanZoomController.abortAnimation(); - } - }); - } - } - - /** - * The different types of Viewport messages handled. All viewport events - * expect a display-port to be returned, but can handle one not being - * returned. - */ - private enum ViewportMessageType { - UPDATE, // The viewport has changed and should be entirely updated - PAGE_SIZE // The viewport's page-size has changed - } - - /** Viewport message handler. */ - private DisplayPortMetrics handleViewportMessage(ImmutableViewportMetrics messageMetrics, ViewportMessageType type) { - synchronized (getLock()) { - ImmutableViewportMetrics newMetrics; - ImmutableViewportMetrics oldMetrics = getViewportMetrics(); - - switch (type) { - default: - case UPDATE: - // Keep the old viewport size - newMetrics = messageMetrics.setViewportSize(oldMetrics.getWidth(), oldMetrics.getHeight()); - if (!oldMetrics.fuzzyEquals(newMetrics)) { - abortPanZoomAnimation(); - } - break; - case PAGE_SIZE: - // adjust the page dimensions to account for differences in zoom - // between the rendered content (which is what Gecko tells us) - // and our zoom level (which may have diverged). - float scaleFactor = oldMetrics.zoomFactor / messageMetrics.zoomFactor; - newMetrics = oldMetrics.setPageRect(RectUtils.scale(messageMetrics.getPageRect(), scaleFactor), messageMetrics.getCssPageRect()); - break; - } - - // Update the Gecko-side viewport metrics. Make sure to do this - // before modifying the metrics below. - final ImmutableViewportMetrics geckoMetrics = newMetrics.clamp(); - post(new Runnable() { - @Override - public void run() { - mGeckoViewport = geckoMetrics; - } - }); - - setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE); - mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null); - } - return mDisplayPort; - } - - //@WrapElementForJNI - DisplayPortMetrics getDisplayPort(boolean pageSizeUpdate, boolean isBrowserContentDisplayed, int tabId, ImmutableViewportMetrics metrics) { - /**Tabs tabs = Tabs.getInstance(); - if (isBrowserContentDisplayed && tabs.isSelectedTabId(tabId)) { - // for foreground tabs, send the viewport update unless the document - // displayed is different from the content document. In that case, just - // calculate the display port. - return handleViewportMessage(metrics, pageSizeUpdate ? ViewportMessageType.PAGE_SIZE : ViewportMessageType.UPDATE); - } else*/ { - // for background tabs, request a new display port calculation, so that - // when we do switch to that tab, we have the correct display port and - // don't need to draw twice (once to allow the first-paint viewport to - // get to java, and again once java figures out the display port). - return DisplayPortCalculator.calculate(metrics, null); - } - } - - //@WrapElementForJNI - void contentDocumentChanged() { - mContentDocumentIsDisplayed = false; - } - - //@WrapElementForJNI - boolean isContentDocumentDisplayed() { - return mContentDocumentIsDisplayed; - } - - // This is called on the Gecko thread to determine if we're still interested - // in the update of this display-port to continue. We can return true here - // to abort the current update and continue with any subsequent ones. This - // is useful for slow-to-render pages when the display-port starts lagging - // behind enough that continuing to draw it is wasted effort. - //@WrapElementForJNI(allowMultithread = true) - public ProgressiveUpdateData progressiveUpdateCallback(boolean aHasPendingNewThebesContent, - float x, float y, float width, float height, - float resolution, boolean lowPrecision) { - // Reset the checkerboard risk flag when switching to low precision - // rendering. - if (lowPrecision && !mLastProgressiveUpdateWasLowPrecision) { - // Skip low precision rendering until we're at risk of checkerboarding. - if (!mProgressiveUpdateWasInDanger) { - mProgressiveUpdateData.abort = true; - return mProgressiveUpdateData; - } - mProgressiveUpdateWasInDanger = false; - } - mLastProgressiveUpdateWasLowPrecision = lowPrecision; - - // Grab a local copy of the last display-port sent to Gecko and the - // current viewport metrics to avoid races when accessing them. - DisplayPortMetrics displayPort = mDisplayPort; - ImmutableViewportMetrics viewportMetrics = mViewportMetrics; - mProgressiveUpdateData.setViewport(viewportMetrics); - mProgressiveUpdateData.abort = false; - - // Always abort updates if the resolution has changed. There's no use - // in drawing at the incorrect resolution. - if (!FloatUtils.fuzzyEquals(resolution, viewportMetrics.zoomFactor)) { - Log.d(LOGTAG, "Aborting draw due to resolution change: " + resolution + " != " + viewportMetrics.zoomFactor); - mProgressiveUpdateData.abort = true; - return mProgressiveUpdateData; - } - - // Store the high precision displayport for comparison when doing low - // precision updates. - if (!lowPrecision) { - if (!FloatUtils.fuzzyEquals(resolution, mProgressiveUpdateDisplayPort.resolution) || - !FloatUtils.fuzzyEquals(x, mProgressiveUpdateDisplayPort.getLeft()) || - !FloatUtils.fuzzyEquals(y, mProgressiveUpdateDisplayPort.getTop()) || - !FloatUtils.fuzzyEquals(x + width, mProgressiveUpdateDisplayPort.getRight()) || - !FloatUtils.fuzzyEquals(y + height, mProgressiveUpdateDisplayPort.getBottom())) { - mProgressiveUpdateDisplayPort = - new DisplayPortMetrics(x, y, x+width, y+height, resolution); - } - } - - // If we're not doing low precision draws and we're about to - // checkerboard, enable low precision drawing. - if (!lowPrecision && !mProgressiveUpdateWasInDanger) { - if (DisplayPortCalculator.aboutToCheckerboard(viewportMetrics, - mPanZoomController.getVelocityVector(), mProgressiveUpdateDisplayPort)) { - mProgressiveUpdateWasInDanger = true; - } - } - - // XXX All sorts of rounding happens inside Gecko that becomes hard to - // account exactly for. Given we align the display-port to tile - // boundaries (and so they rarely vary by sub-pixel amounts), just - // check that values are within a couple of pixels of the - // display-port bounds. - - // Never abort drawing if we can't be sure we've sent a more recent - // display-port. If we abort updating when we shouldn't, we can end up - // with blank regions on the screen and we open up the risk of entering - // an endless updating cycle. - if (Math.abs(displayPort.getLeft() - mProgressiveUpdateDisplayPort.getLeft()) <= 2 && - Math.abs(displayPort.getTop() - mProgressiveUpdateDisplayPort.getTop()) <= 2 && - Math.abs(displayPort.getBottom() - mProgressiveUpdateDisplayPort.getBottom()) <= 2 && - Math.abs(displayPort.getRight() - mProgressiveUpdateDisplayPort.getRight()) <= 2) { - return mProgressiveUpdateData; - } - - // Abort updates when the display-port no longer contains the visible - // area of the page (that is, the viewport cropped by the page - // boundaries). - // XXX This makes the assumption that we never let the visible area of - // the page fall outside of the display-port. - if (Math.max(viewportMetrics.viewportRectLeft, viewportMetrics.pageRectLeft) + 1 < x || - Math.max(viewportMetrics.viewportRectTop, viewportMetrics.pageRectTop) + 1 < y || - Math.min(viewportMetrics.viewportRectRight, viewportMetrics.pageRectRight) - 1 > x + width || - Math.min(viewportMetrics.viewportRectBottom, viewportMetrics.pageRectBottom) - 1 > y + height) { - Log.d(LOGTAG, "Aborting update due to viewport not in display-port"); - mProgressiveUpdateData.abort = true; - - // Enable low-precision drawing, as we're likely to be in danger if - // this situation has been encountered. - mProgressiveUpdateWasInDanger = true; - - return mProgressiveUpdateData; - } - - // Abort drawing stale low-precision content if there's a more recent - // display-port in the pipeline. - if (lowPrecision && !aHasPendingNewThebesContent) { - mProgressiveUpdateData.abort = true; - } - return mProgressiveUpdateData; - } - - void setZoomConstraints(ZoomConstraints constraints) { - mZoomConstraints = constraints; - } - - void setIsRTL(boolean aIsRTL) { - synchronized (getLock()) { - ImmutableViewportMetrics newMetrics = getViewportMetrics().setIsRTL(aIsRTL); - setViewportMetrics(newMetrics, false); - } - } - - /** The compositor invokes this function just before compositing a frame where the document - * is different from the document composited on the last frame. In these cases, the viewport - * information we have in Java is no longer valid and needs to be replaced with the new - * viewport information provided. setPageRect will never be invoked on the same frame that - * this function is invoked on; and this function will always be called prior to syncViewportInfo. - */ - //@WrapElementForJNI(allowMultithread = true) - public void setFirstPaintViewport(float offsetX, float offsetY, float zoom, - float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { - synchronized (getLock()) { - ImmutableViewportMetrics currentMetrics = getViewportMetrics(); - - //Tab tab = Tabs.getInstance().getSelectedTab(); - - RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); - RectF pageRect = RectUtils.scaleAndRound(cssPageRect, zoom); - - final ImmutableViewportMetrics newMetrics = currentMetrics - .setViewportOrigin(offsetX, offsetY) - .setZoomFactor(zoom) - .setPageRect(pageRect, cssPageRect) - /*.setIsRTL(tab.getIsRTL())*/; - // Since we have switched to displaying a different document, we need to update any - // viewport-related state we have lying around. This includes mGeckoViewport and - // mViewportMetrics. Usually this information is updated via handleViewportMessage - // while we remain on the same document. - post(new Runnable() { - @Override - public void run() { - mGeckoViewport = newMetrics; - } - }); - - setViewportMetrics(newMetrics); - - //mView.setBackgroundColor(tab.getBackgroundColor()); - //setZoomConstraints(tab.getZoomConstraints()); - - // At this point, we have just switched to displaying a different document than we - // we previously displaying. This means we need to abort any panning/zooming animations - // that are in progress and send an updated display port request to browser.js as soon - // as possible. The call to PanZoomController.abortAnimation accomplishes this by calling the - // forceRedraw function, which sends the viewport to gecko. The display port request is - // actually a full viewport update, which is fine because if browser.js has somehow moved to - // be out of sync with this first-paint viewport, then we force them back in sync. - abortPanZoomAnimation(); - - // Indicate that the document is about to be composited so the - // LayerView background can be removed. - if (mView.getPaintState() == LayerView.PAINT_START) { - mView.setPaintState(LayerView.PAINT_BEFORE_FIRST); - } - } - DisplayPortCalculator.resetPageState(); - mDrawTimingQueue.reset(); - - mContentDocumentIsDisplayed = true; - } - - /** The compositor invokes this function whenever it determines that the page rect - * has changed (based on the information it gets from layout). If setFirstPaintViewport - * is invoked on a frame, then this function will not be. For any given frame, this - * function will be invoked before syncViewportInfo. - */ - //@WrapElementForJNI(allowMultithread = true) - public void setPageRect(float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom) { - synchronized (getLock()) { - RectF cssPageRect = new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); - float ourZoom = getViewportMetrics().zoomFactor; - setPageRect(RectUtils.scale(cssPageRect, ourZoom), cssPageRect); - // Here the page size of the document has changed, but the document being displayed - // is still the same. Therefore, we don't need to send anything to browser.js; any - // changes we need to make to the display port will get sent the next time we call - // adjustViewport(). - } - } - - /** The compositor invokes this function on every frame to figure out what part of the - * page to display, and to inform Java of the current display port. Since it is called - * on every frame, it needs to be ultra-fast. - * It avoids taking any locks or allocating any objects. We keep around a - * mCurrentViewTransform so we don't need to allocate a new ViewTransform - * every time we're called. NOTE: we might be able to return a ImmutableViewportMetrics - * which would avoid the copy into mCurrentViewTransform. - */ - //@WrapElementForJNI(allowMultithread = true) - public ViewTransform syncViewportInfo(int x, int y, int width, int height, float resolution, boolean layersUpdated) { - // getViewportMetrics is thread safe so we don't need to synchronize. - // We save the viewport metrics here, so we later use it later in - // createFrame (which will be called by nsWindow::DrawWindowUnderlay on - // the native side, by the compositor). The viewport - // metrics can change between here and there, as it's accessed outside - // of the compositor thread. - mFrameMetrics = getViewportMetrics(); - - mCurrentViewTransform.x = mFrameMetrics.viewportRectLeft; - mCurrentViewTransform.y = mFrameMetrics.viewportRectTop; - mCurrentViewTransform.scale = mFrameMetrics.zoomFactor; - - // Adjust the fixed layer margins so that overscroll subtracts from them. - getFixedMargins(mFrameMetrics, mCurrentViewTransformMargins); - mCurrentViewTransform.fixedLayerMarginLeft = mCurrentViewTransformMargins.left; - mCurrentViewTransform.fixedLayerMarginTop = mCurrentViewTransformMargins.top; - mCurrentViewTransform.fixedLayerMarginRight = mCurrentViewTransformMargins.right; - mCurrentViewTransform.fixedLayerMarginBottom = mCurrentViewTransformMargins.bottom; - - // Offset the view transform so that it renders in the correct place. - PointF offset = mFrameMetrics.getMarginOffset(); - mCurrentViewTransform.offsetX = offset.x; - mCurrentViewTransform.offsetY = offset.y; - - mRootLayer.setPositionAndResolution( - Math.round(x + mCurrentViewTransform.offsetX), - Math.round(y + mCurrentViewTransform.offsetY), - Math.round(x + width + mCurrentViewTransform.offsetX), - Math.round(y + height + mCurrentViewTransform.offsetY), - resolution); - - if (layersUpdated && mRecordDrawTimes) { - // If we got a layers update, that means a draw finished. Check to see if the area drawn matches - // one of our requested displayports; if it does calculate the draw time and notify the - // DisplayPortCalculator - DisplayPortMetrics drawn = new DisplayPortMetrics(x, y, x + width, y + height, resolution); - long time = mDrawTimingQueue.findTimeFor(drawn); - if (time >= 0) { - long now = SystemClock.uptimeMillis(); - time = now - time; - mRecordDrawTimes = DisplayPortCalculator.drawTimeUpdate(time, width * height); - } - } - - if (layersUpdated && mDrawListener != null) { - /* Used by robocop for testing purposes */ - mDrawListener.drawFinished(); - } - - return mCurrentViewTransform; - } - - //@WrapElementForJNI(allowMultithread = true) - public ViewTransform syncFrameMetrics(float offsetX, float offsetY, float zoom, - float cssPageLeft, float cssPageTop, float cssPageRight, float cssPageBottom, - boolean layersUpdated, int x, int y, int width, int height, float resolution, - boolean isFirstPaint) - { - if (isFirstPaint) { - setFirstPaintViewport(offsetX, offsetY, zoom, - cssPageLeft, cssPageTop, cssPageRight, cssPageBottom); - } - - return syncViewportInfo(x, y, width, height, resolution, layersUpdated); - } - - //@WrapElementForJNI(allowMultithread = true) - public LayerRenderer.Frame createFrame() { - // Create the shaders and textures if necessary. - if (!mLayerRendererInitialized) { - mLayerRenderer.checkMonitoringEnabled(); - mLayerRenderer.createDefaultProgram(); - mLayerRendererInitialized = true; - } - - return mLayerRenderer.createFrame(mFrameMetrics); - } - - //@WrapElementForJNI(allowMultithread = true) - public void activateProgram() { - mLayerRenderer.activateDefaultProgram(); - } - - //@WrapElementForJNI(allowMultithread = true) - public void deactivateProgram() { - mLayerRenderer.deactivateDefaultProgram(); - } - - private void geometryChanged(DisplayPortMetrics displayPort) { - /* Let Gecko know if the screensize has changed */ - sendResizeEventIfNecessary(false); - if (getRedrawHint()) { - adjustViewport(displayPort); - } - } - - /** Implementation of LayerView.Listener */ - @Override - public void renderRequested() { - try { - //GeckoAppShell.scheduleComposite(); - } catch (UnsupportedOperationException uoe) { - // In some very rare cases this gets called before libxul is loaded, - // so catch and ignore the exception that will throw. See bug 837821 - Log.d(LOGTAG, "Dropping renderRequested call before libxul load."); - } - } - - /** Implementation of LayerView.Listener */ - @Override - public void sizeChanged(int width, int height) { - // We need to make sure a draw happens synchronously at this point, - // but resizing the surface before the SurfaceView has resized will - // cause a visible jump. - mView.getGLController().resumeCompositor(mWindowSize.width, mWindowSize.height); - } - - /** Implementation of LayerView.Listener */ - @Override - public void surfaceChanged(int width, int height) { - setViewportSize(width, height); - } - - /** Implementation of PanZoomTarget */ - @Override - public ImmutableViewportMetrics getViewportMetrics() { - return mViewportMetrics; - } - - /** Implementation of PanZoomTarget */ - @Override - public ZoomConstraints getZoomConstraints() { - return mZoomConstraints; - } - - /** Implementation of PanZoomTarget */ - @Override - public boolean isFullScreen() { - return mView.isFullScreen(); - } - - /** Implementation of PanZoomTarget */ - @Override - public RectF getMaxMargins() { - return mMarginsAnimator.getMaxMargins(); - } - - /** Implementation of PanZoomTarget */ - @Override - public void setAnimationTarget(ImmutableViewportMetrics metrics) { - if (mGeckoIsReady) { - // We know what the final viewport of the animation is going to be, so - // immediately request a draw of that area by setting the display port - // accordingly. This way we should have the content pre-rendered by the - // time the animation is done. - DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null); - adjustViewport(displayPort); - } - } - - /** Implementation of PanZoomTarget - * You must hold the monitor while calling this. - */ - @Override - public void setViewportMetrics(ImmutableViewportMetrics metrics) { - setViewportMetrics(metrics, true); - } - - /* - * You must hold the monitor while calling this. - */ - private void setViewportMetrics(ImmutableViewportMetrics metrics, boolean notifyGecko) { - // This class owns the viewport size and the fixed layer margins; don't let other pieces - // of code clobber either of them. The only place the viewport size should ever be - // updated is in GeckoLayerClient.setViewportSize, and the only place the margins should - // ever be updated is in GeckoLayerClient.setFixedLayerMargins; both of these assign to - // mViewportMetrics directly. - metrics = metrics.setViewportSize(mViewportMetrics.getWidth(), mViewportMetrics.getHeight()); - metrics = metrics.setMarginsFrom(mViewportMetrics); - mViewportMetrics = metrics; - - viewportMetricsChanged(notifyGecko); - } - - /* - * You must hold the monitor while calling this. - */ - private void viewportMetricsChanged(boolean notifyGecko) { - if (mViewportChangeListener != null) { - mViewportChangeListener.onMetricsChanged(mViewportMetrics); - } - - mView.requestRender(); - if (notifyGecko && mGeckoIsReady) { - geometryChanged(null); - } - } - - /* - * Updates the viewport metrics, overriding the viewport size and margins - * which are normally retained when calling setViewportMetrics. - * You must hold the monitor while calling this. - */ - void forceViewportMetrics(ImmutableViewportMetrics metrics, boolean notifyGecko, boolean forceRedraw) { - if (forceRedraw) { - mForceRedraw = true; - } - mViewportMetrics = metrics; - viewportMetricsChanged(notifyGecko); - } - - /** Implementation of PanZoomTarget - * Scroll the viewport by a certain amount. This will take viewport margins - * and margin animation into account. If margins are currently animating, - * this will just go ahead and modify the viewport origin, otherwise the - * delta will be applied to the margins and the remainder will be applied to - * the viewport origin. - * - * You must hold the monitor while calling this. - */ - @Override - public void scrollBy(float dx, float dy) { - // Set mViewportMetrics manually so the margin changes take. - mViewportMetrics = mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy); - viewportMetricsChanged(true); - } - - /** Implementation of PanZoomTarget - * Notification that a subdocument has been scrolled by a certain amount. - * This is used here to make sure that the margins are still accessible - * during subdocument scrolling. - * - * You must hold the monitor while calling this. - */ - @Override - public void scrollMarginsBy(float dx, float dy) { - ImmutableViewportMetrics newMarginsMetrics = - mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy); - mViewportMetrics = mViewportMetrics.setMarginsFrom(newMarginsMetrics); - viewportMetricsChanged(true); - } - - /** Implementation of PanZoomTarget */ - @Override - public void panZoomStopped() { - if (mViewportChangeListener != null) { - mViewportChangeListener.onPanZoomStopped(); - } - } - - public interface OnMetricsChangedListener { - public void onMetricsChanged(ImmutableViewportMetrics viewport); - public void onPanZoomStopped(); - } - - /** Implementation of PanZoomTarget */ - @Override - public void forceRedraw(DisplayPortMetrics displayPort) { - mForceRedraw = true; - if (mGeckoIsReady) { - geometryChanged(displayPort); - } - } - - /** Implementation of PanZoomTarget */ - @Override - public boolean post(Runnable action) { - return mView.post(action); - } - - /** Implementation of PanZoomTarget */ - @Override - public void postRenderTask(RenderTask task) { - mView.postRenderTask(task); - } - - /** Implementation of PanZoomTarget */ - @Override - public void removeRenderTask(RenderTask task) { - mView.removeRenderTask(task); - } - - - /** Implementation of PanZoomTarget */ - @Override - public boolean postDelayed(Runnable action, long delayMillis) { - return mView.postDelayed(action, delayMillis); - } - - /** Implementation of PanZoomTarget */ - @Override - public Object getLock() { - return this; - } - - /** Implementation of PanZoomTarget - * Converts a point from layer view coordinates to layer coordinates. In other words, given a - * point measured in pixels from the top left corner of the layer view, returns the point in - * pixels measured from the last scroll position we sent to Gecko, in CSS pixels. Assuming the - * events being sent to Gecko are processed in FIFO order, this calculation should always be - * correct. - */ - @Override - public PointF convertViewPointToLayerPoint(PointF viewPoint) { - if (!mGeckoIsReady) { - return null; - } - - ImmutableViewportMetrics viewportMetrics = mViewportMetrics; - PointF origin = viewportMetrics.getOrigin(); - PointF offset = viewportMetrics.getMarginOffset(); - origin.offset(-offset.x, -offset.y); - float zoom = viewportMetrics.zoomFactor; - ImmutableViewportMetrics geckoViewport = mGeckoViewport; - PointF geckoOrigin = geckoViewport.getOrigin(); - float geckoZoom = geckoViewport.zoomFactor; - - // viewPoint + origin - offset gives the coordinate in device pixels from the top-left corner of the page. - // Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page. - // geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from - // the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint from - // the current Gecko coordinate in CSS pixels. - PointF layerPoint = new PointF( - ((viewPoint.x + origin.x) / zoom) - (geckoOrigin.x / geckoZoom), - ((viewPoint.y + origin.y) / zoom) - (geckoOrigin.y / geckoZoom)); - - return layerPoint; - } - - public void setOnMetricsChangedListener(OnMetricsChangedListener listener) { - mViewportChangeListener = listener; - } - - /** Used by robocop for testing purposes. Not for production use! */ - //@RobocopTarget - public void setDrawListener(DrawListener listener) { - mDrawListener = listener; - } - - /** Used by robocop for testing purposes. Not for production use! */ - //@RobocopTarget - public static interface DrawListener { - public void drawFinished(); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java deleted file mode 100644 index 463bc3c4a4a5..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ImmutableViewportMetrics.java +++ /dev/null @@ -1,374 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -import org.mozilla.gecko.util.FloatUtils; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.DisplayMetrics; - -/** - * ImmutableViewportMetrics are used to store the viewport metrics - * in way that we can access a version of them from multiple threads - * without having to take a lock - */ -public class ImmutableViewportMetrics { - - // We need to flatten the RectF and FloatSize structures - // because Java doesn't have the concept of const classes - public final float pageRectLeft; - public final float pageRectTop; - public final float pageRectRight; - public final float pageRectBottom; - public final float cssPageRectLeft; - public final float cssPageRectTop; - public final float cssPageRectRight; - public final float cssPageRectBottom; - public final float viewportRectLeft; - public final float viewportRectTop; - public final float viewportRectRight; - public final float viewportRectBottom; - public final float marginLeft; - public final float marginTop; - public final float marginRight; - public final float marginBottom; - public final float zoomFactor; - public final boolean isRTL; - - public ImmutableViewportMetrics(DisplayMetrics metrics) { - viewportRectLeft = pageRectLeft = cssPageRectLeft = 0; - viewportRectTop = pageRectTop = cssPageRectTop = 0; - viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels; - viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels; - marginLeft = marginTop = marginRight = marginBottom = 0; - zoomFactor = 1.0f; - isRTL = false; - } - - /** This constructor is used by native code in AndroidJavaWrappers.cpp, be - * careful when modifying the signature. - */ - //@WrapElementForJNI(allowMultithread = true) - public ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, - float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, - float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, - float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, - float aViewportRectBottom, float aZoomFactor) - { - this(aPageRectLeft, aPageRectTop, - aPageRectRight, aPageRectBottom, aCssPageRectLeft, - aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom, - aViewportRectLeft, aViewportRectTop, aViewportRectRight, - aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor, false); - } - - private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop, - float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft, - float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom, - float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight, - float aViewportRectBottom, float aMarginLeft, - float aMarginTop, float aMarginRight, - float aMarginBottom, float aZoomFactor, boolean aIsRTL) - { - pageRectLeft = aPageRectLeft; - pageRectTop = aPageRectTop; - pageRectRight = aPageRectRight; - pageRectBottom = aPageRectBottom; - cssPageRectLeft = aCssPageRectLeft; - cssPageRectTop = aCssPageRectTop; - cssPageRectRight = aCssPageRectRight; - cssPageRectBottom = aCssPageRectBottom; - viewportRectLeft = aViewportRectLeft; - viewportRectTop = aViewportRectTop; - viewportRectRight = aViewportRectRight; - viewportRectBottom = aViewportRectBottom; - marginLeft = aMarginLeft; - marginTop = aMarginTop; - marginRight = aMarginRight; - marginBottom = aMarginBottom; - zoomFactor = aZoomFactor; - isRTL = aIsRTL; - } - - public float getWidth() { - return viewportRectRight - viewportRectLeft; - } - - public float getHeight() { - return viewportRectBottom - viewportRectTop; - } - - public float getWidthWithoutMargins() { - return viewportRectRight - viewportRectLeft - marginLeft - marginRight; - } - - public float getHeightWithoutMargins() { - return viewportRectBottom - viewportRectTop - marginTop - marginBottom; - } - - public PointF getOrigin() { - return new PointF(viewportRectLeft, viewportRectTop); - } - - public PointF getMarginOffset() { - if (isRTL) { - return new PointF(marginLeft - marginRight, marginTop); - } - return new PointF(marginLeft, marginTop); - } - - public FloatSize getSize() { - return new FloatSize(viewportRectRight - viewportRectLeft, viewportRectBottom - viewportRectTop); - } - - public RectF getViewport() { - return new RectF(viewportRectLeft, - viewportRectTop, - viewportRectRight, - viewportRectBottom); - } - - public RectF getCssViewport() { - return RectUtils.scale(getViewport(), 1/zoomFactor); - } - - public RectF getPageRect() { - return new RectF(pageRectLeft, pageRectTop, pageRectRight, pageRectBottom); - } - - public float getPageWidth() { - return pageRectRight - pageRectLeft; - } - - public float getPageWidthWithMargins() { - return (pageRectRight - pageRectLeft) + marginLeft + marginRight; - } - - public float getPageHeight() { - return pageRectBottom - pageRectTop; - } - - public float getPageHeightWithMargins() { - return (pageRectBottom - pageRectTop) + marginTop + marginBottom; - } - - public RectF getCssPageRect() { - return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom); - } - - public RectF getOverscroll() { - return new RectF(Math.max(0, pageRectLeft - viewportRectLeft), - Math.max(0, pageRectTop - viewportRectTop), - Math.max(0, viewportRectRight - pageRectRight), - Math.max(0, viewportRectBottom - pageRectBottom)); - } - - /* - * Returns the viewport metrics that represent a linear transition between "this" and "to" at - * time "t", which is on the scale [0, 1). This function interpolates all values stored in - * the viewport metrics. - */ - public ImmutableViewportMetrics interpolate(ImmutableViewportMetrics to, float t) { - return new ImmutableViewportMetrics( - FloatUtils.interpolate(pageRectLeft, to.pageRectLeft, t), - FloatUtils.interpolate(pageRectTop, to.pageRectTop, t), - FloatUtils.interpolate(pageRectRight, to.pageRectRight, t), - FloatUtils.interpolate(pageRectBottom, to.pageRectBottom, t), - FloatUtils.interpolate(cssPageRectLeft, to.cssPageRectLeft, t), - FloatUtils.interpolate(cssPageRectTop, to.cssPageRectTop, t), - FloatUtils.interpolate(cssPageRectRight, to.cssPageRectRight, t), - FloatUtils.interpolate(cssPageRectBottom, to.cssPageRectBottom, t), - FloatUtils.interpolate(viewportRectLeft, to.viewportRectLeft, t), - FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t), - FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t), - FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t), - FloatUtils.interpolate(marginLeft, to.marginLeft, t), - FloatUtils.interpolate(marginTop, to.marginTop, t), - FloatUtils.interpolate(marginRight, to.marginRight, t), - FloatUtils.interpolate(marginBottom, to.marginBottom, t), - FloatUtils.interpolate(zoomFactor, to.zoomFactor, t), - t >= 0.5 ? to.isRTL : isRTL); - } - - public ImmutableViewportMetrics setViewportSize(float width, float height) { - if (FloatUtils.fuzzyEquals(width, getWidth()) && FloatUtils.fuzzyEquals(height, getHeight())) { - return this; - } - - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height, - marginLeft, marginTop, marginRight, marginBottom, - zoomFactor, isRTL); - } - - public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) { - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(), - marginLeft, marginTop, marginRight, marginBottom, - zoomFactor, isRTL); - } - - public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) { - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, - marginLeft, marginTop, marginRight, marginBottom, - newZoomFactor, isRTL); - } - - public ImmutableViewportMetrics offsetViewportBy(float dx, float dy) { - return setViewportOrigin(viewportRectLeft + dx, viewportRectTop + dy); - } - - public ImmutableViewportMetrics offsetViewportByAndClamp(float dx, float dy) { - if (isRTL) { - return setViewportOrigin( - Math.min(pageRectRight - getWidthWithoutMargins(), Math.max(viewportRectLeft + dx, pageRectLeft)), - Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins()))); - } - return setViewportOrigin( - Math.max(pageRectLeft, Math.min(viewportRectLeft + dx, pageRectRight - getWidthWithoutMargins())), - Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins()))); - } - - public ImmutableViewportMetrics setPageRect(RectF pageRect, RectF cssPageRect) { - return new ImmutableViewportMetrics( - pageRect.left, pageRect.top, pageRect.right, pageRect.bottom, - cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom, - viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, - marginLeft, marginTop, marginRight, marginBottom, - zoomFactor, isRTL); - } - - public ImmutableViewportMetrics setMargins(float left, float top, float right, float bottom) { - if (FloatUtils.fuzzyEquals(left, marginLeft) - && FloatUtils.fuzzyEquals(top, marginTop) - && FloatUtils.fuzzyEquals(right, marginRight) - && FloatUtils.fuzzyEquals(bottom, marginBottom)) { - return this; - } - - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, - left, top, right, bottom, zoomFactor, isRTL); - } - - public ImmutableViewportMetrics setMarginsFrom(ImmutableViewportMetrics fromMetrics) { - return setMargins(fromMetrics.marginLeft, - fromMetrics.marginTop, - fromMetrics.marginRight, - fromMetrics.marginBottom); - } - - public ImmutableViewportMetrics setIsRTL(boolean aIsRTL) { - if (isRTL == aIsRTL) { - return this; - } - - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom, - marginLeft, marginTop, marginRight, marginBottom, zoomFactor, aIsRTL); - } - - /* This will set the zoom factor and re-scale page-size and viewport offset - * accordingly. The given focus will remain at the same point on the screen - * after scaling. - */ - public ImmutableViewportMetrics scaleTo(float newZoomFactor, PointF focus) { - // cssPageRect* is invariant, since we're setting the scale factor - // here. The page rect is based on the CSS page rect. - float newPageRectLeft = cssPageRectLeft * newZoomFactor; - float newPageRectTop = cssPageRectTop * newZoomFactor; - float newPageRectRight = cssPageRectLeft + ((cssPageRectRight - cssPageRectLeft) * newZoomFactor); - float newPageRectBottom = cssPageRectTop + ((cssPageRectBottom - cssPageRectTop) * newZoomFactor); - - PointF origin = getOrigin(); - origin.offset(focus.x, focus.y); - origin = PointUtils.scale(origin, newZoomFactor / zoomFactor); - origin.offset(-focus.x, -focus.y); - - return new ImmutableViewportMetrics( - newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(), - marginLeft, marginTop, marginRight, marginBottom, - newZoomFactor, isRTL); - } - - /** Clamps the viewport to remain within the page rect. */ - private ImmutableViewportMetrics clamp(float marginLeft, float marginTop, - float marginRight, float marginBottom) { - RectF newViewport = getViewport(); - PointF offset = getMarginOffset(); - - // The viewport bounds ought to never exceed the page bounds. - if (newViewport.right > pageRectRight + marginLeft + marginRight) - newViewport.offset((pageRectRight + marginLeft + marginRight) - newViewport.right, 0); - if (newViewport.left < pageRectLeft) - newViewport.offset(pageRectLeft - newViewport.left, 0); - - if (newViewport.bottom > pageRectBottom + marginTop + marginBottom) - newViewport.offset(0, (pageRectBottom + marginTop + marginBottom) - newViewport.bottom); - if (newViewport.top < pageRectTop) - newViewport.offset(0, pageRectTop - newViewport.top); - - return new ImmutableViewportMetrics( - pageRectLeft, pageRectTop, pageRectRight, pageRectBottom, - cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom, - newViewport.left, newViewport.top, newViewport.right, newViewport.bottom, - marginLeft, marginTop, marginRight, marginBottom, - zoomFactor, isRTL); - } - - public ImmutableViewportMetrics clamp() { - return clamp(0, 0, 0, 0); - } - - public ImmutableViewportMetrics clampWithMargins() { - return clamp(marginLeft, marginTop, - marginRight, marginBottom); - } - - public boolean fuzzyEquals(ImmutableViewportMetrics other) { - // Don't bother checking the pageRectXXX values because they are a product - // of the cssPageRectXXX values and the zoomFactor, except with more rounding - // error. Checking those is both inefficient and can lead to false negatives. - // - // This doesn't return false if the margins differ as none of the users - // of this function are interested in the margins in that way. - return FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft) - && FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop) - && FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight) - && FloatUtils.fuzzyEquals(cssPageRectBottom, other.cssPageRectBottom) - && FloatUtils.fuzzyEquals(viewportRectLeft, other.viewportRectLeft) - && FloatUtils.fuzzyEquals(viewportRectTop, other.viewportRectTop) - && FloatUtils.fuzzyEquals(viewportRectRight, other.viewportRectRight) - && FloatUtils.fuzzyEquals(viewportRectBottom, other.viewportRectBottom) - && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor); - } - - @Override - public String toString() { - return "ImmutableViewportMetrics v=(" + viewportRectLeft + "," + viewportRectTop + "," - + viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + "," - + pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=(" - + cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + "," - + cssPageRectBottom + ") m=(" + marginLeft + "," - + marginTop + "," + marginRight + "," - + marginBottom + ") z=" + zoomFactor + ", rtl=" + isRTL; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java deleted file mode 100644 index 9b3ca381b5a4..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.os.Handler; -import android.view.KeyEvent; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; - -public interface InputConnectionHandler -{ - Handler getHandler(Handler defHandler); - InputConnection onCreateInputConnection(EditorInfo outAttrs); - boolean onKeyPreIme(int keyCode, KeyEvent event); - boolean onKeyDown(int keyCode, KeyEvent event); - boolean onKeyLongPress(int keyCode, KeyEvent event); - boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event); - boolean onKeyUp(int keyCode, KeyEvent event); - boolean isIMEEnabled(); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java deleted file mode 100644 index b758d732c2ed..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.util.FloatMath; - -public class IntSize { - public final int width, height; - - public IntSize(IntSize size) { width = size.width; height = size.height; } - public IntSize(int inWidth, int inHeight) { width = inWidth; height = inHeight; } - - public IntSize(FloatSize size) { - width = Math.round(size.width); - height = Math.round(size.height); - } - - public IntSize(JSONObject json) { - try { - width = json.getInt("width"); - height = json.getInt("height"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - public int getArea() { - return width * height; - } - - public boolean equals(IntSize size) { - return ((size.width == width) && (size.height == height)); - } - - public boolean isPositive() { - return (width > 0 && height > 0); - } - - @Override - public String toString() { return "(" + width + "," + height + ")"; } - - public IntSize scale(float factor) { - return new IntSize(Math.round(width * factor), - Math.round(height * factor)); - } - - /* Returns the power of two that is greater than or equal to value */ - public static int nextPowerOfTwo(int value) { - // code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html - if (0 == value--) { - return 1; - } - value = (value >> 1) | value; - value = (value >> 2) | value; - value = (value >> 4) | value; - value = (value >> 8) | value; - value = (value >> 16) | value; - return value + 1; - } - - public IntSize nextPowerOfTwo() { - return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height)); - } - - public static boolean isPowerOfTwo(int value) { - if (value == 0) - return false; - return (value & (value - 1)) == 0; - } - - public static int largestPowerOfTwoLessThan(float value) { - int val = (int)FloatMath.floor(value); - if (val <= 0) { - throw new IllegalArgumentException("Error: value must be > 0"); - } - // keep dropping the least-significant set bits until only one is left - int bestVal = val; - while (val != 0) { - bestVal = val; - val &= (val - 1); - } - return bestVal; - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java deleted file mode 100644 index ac1bf0d3d451..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/JavaPanZoomController.java +++ /dev/null @@ -1,1461 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -//import org.mozilla.gecko.PrefsHelper; -//import org.mozilla.gecko.Tab; -//import org.mozilla.gecko.Tabs; -import org.mozilla.gecko.ZoomConstraints; -import org.mozilla.gecko.util.EventDispatcher; -import org.mozilla.gecko.util.FloatUtils; -//import org.mozilla.gecko.util.GamepadUtils; -import org.mozilla.gecko.util.GeckoEventListener; -import org.mozilla.gecko.util.ThreadUtils; - -import org.json.JSONObject; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.os.Build; -import android.util.FloatMath; -import android.util.Log; -import android.view.GestureDetector; -import android.view.InputDevice; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; - -/* - * Handles the kinetic scrolling and zooming physics for a layer controller. - * - * Many ideas are from Joe Hewitt's Scrollability: - * https://github.com/joehewitt/scrollability/ - */ -class JavaPanZoomController - extends GestureDetector.SimpleOnGestureListener - implements PanZoomController, SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener -{ - private static final String LOGTAG = "GeckoPanZoomController"; - - private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect"; - private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth"; - private static String MESSAGE_TOUCH_LISTENER = "Tab:HasTouchListener"; - - // Animation stops if the velocity is below this value when overscrolled or panning. - private static final float STOPPED_THRESHOLD = 4.0f; - - // Animation stops is the velocity is below this threshold when flinging. - private static final float FLING_STOPPED_THRESHOLD = 0.1f; - - // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans - // between the touch-down and touch-up of a click). In units of density-independent pixels. - public static final float PAN_THRESHOLD = 1/16f * LOKitShell.getDpi(); //GeckoAppShell.getDpi(); - - // Angle from axis within which we stay axis-locked - private static final double AXIS_LOCK_ANGLE = Math.PI / 6.0; // 30 degrees - - // Axis-lock breakout angle - private static final double AXIS_BREAKOUT_ANGLE = Math.PI / 8.0; - - // The distance the user has to pan before we consider breaking out of a locked axis - public static final float AXIS_BREAKOUT_THRESHOLD = 1/32f * LOKitShell.getDpi(); //GeckoAppShell.getDpi(); - - // The maximum amount we allow you to zoom into a page - private static final float MAX_ZOOM = 4.0f; - - // The maximum amount we would like to scroll with the mouse - private static final float MAX_SCROLL = 0.075f * LOKitShell.getDpi(); - - // The maximum zoom factor adjustment per frame of the AUTONAV animation - private static final float MAX_ZOOM_DELTA = 0.125f; - - // The duration of the bounce animation in ns - private static final int BOUNCE_ANIMATION_DURATION = 250000000; - - private enum PanZoomState { - NOTHING, /* no touch-start events received */ - FLING, /* all touches removed, but we're still scrolling page */ - TOUCHING, /* one touch-start event received */ - PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis lock) X axis */ - PANNING_LOCKED_Y, /* as above for Y axis */ - PANNING, /* panning without axis lock */ - PANNING_HOLD, /* in panning, but not moving. - * similar to TOUCHING but after starting a pan */ - PANNING_HOLD_LOCKED_X, /* like PANNING_HOLD, but axis lock still in effect for X axis */ - PANNING_HOLD_LOCKED_Y, /* as above but for Y axis */ - PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */ - ANIMATED_ZOOM, /* animated zoom to a new rect */ - BOUNCE, /* in a bounce animation */ - WAITING_LISTENERS, /* a state halfway between NOTHING and TOUCHING - the user has - put a finger down, but we don't yet know if a touch listener has - prevented the default actions yet. we still need to abort animations. */ - AUTONAV, /* We are scrolling using an AutonavRunnable animation. This is similar - to the FLING state except that it must be stopped manually by the code that - started it, and it's velocity can be updated while it's running. */ - } - - private enum AxisLockMode { - STANDARD, /* Default axis locking mode that doesn't break out until finger release */ - FREE, /* No locking at all */ - STICKY /* Break out with hysteresis so that it feels as free as possible whilst locking */ - } - - private final PanZoomTarget mTarget; - private final SubdocumentScrollHelper mSubscroller; - private final Axis mX; - private final Axis mY; - private final TouchEventHandler mTouchEventHandler; - private final EventDispatcher mEventDispatcher; - - /* The task that handles flings, autonav or bounces. */ - private PanZoomRenderTask mAnimationRenderTask; - /* The zoom focus at the first zoom event (in page coordinates). */ - private PointF mLastZoomFocus; - /* The time the last motion event took place. */ - private long mLastEventTime; - /* Current state the pan/zoom UI is in. */ - private PanZoomState mState; - /* The per-frame zoom delta for the currently-running AUTONAV animation. */ - private float mAutonavZoomDelta; - /* The user selected panning mode */ - private AxisLockMode mMode; - /* A medium-length tap/press is happening */ - private boolean mMediumPress; - /* Used to change the scrollY direction */ - private boolean mNegateWheelScrollY; - /* Whether the current event has been default-prevented. */ - private boolean mDefaultPrevented; - - // Handler to be notified when overscroll occurs - private Overscroll mOverscroll; - - public JavaPanZoomController(PanZoomTarget target, View view, EventDispatcher eventDispatcher) { - mTarget = target; - mSubscroller = new SubdocumentScrollHelper(eventDispatcher); - mX = new AxisX(mSubscroller); - mY = new AxisY(mSubscroller); - mTouchEventHandler = new TouchEventHandler(view.getContext(), view, this); - - checkMainThread(); - - setState(PanZoomState.NOTHING); - - mEventDispatcher = eventDispatcher; - registerEventListener(MESSAGE_ZOOM_RECT); - registerEventListener(MESSAGE_ZOOM_PAGE); - registerEventListener(MESSAGE_TOUCH_LISTENER); - - mMode = AxisLockMode.STANDARD; - - String[] prefs = { "ui.scrolling.axis_lock_mode", - "ui.scrolling.negate_wheel_scrollY", - "ui.scrolling.gamepad_dead_zone" }; - mNegateWheelScrollY = false; - - /*PrefsHelper.getPrefs(prefs, new PrefsHelper.PrefHandlerBase() { - @Override public void prefValue(String pref, String value) { - if (pref.equals("ui.scrolling.axis_lock_mode")) { - if (value.equals("standard")) { - mMode = AxisLockMode.STANDARD; - } else if (value.equals("free")) { - mMode = AxisLockMode.FREE; - } else { - mMode = AxisLockMode.STICKY; - } - } - } - - @Override public void prefValue(String pref, int value) { - if (pref.equals("ui.scrolling.gamepad_dead_zone")) { - GamepadUtils.overrideDeadZoneThreshold((float)value / 1000f); - } - } - - @Override public void prefValue(String pref, boolean value) { - if (pref.equals("ui.scrolling.negate_wheel_scrollY")) { - mNegateWheelScrollY = value; - } - } - - @Override - public boolean isObserver() { - return true; - } - });*/ - - Axis.initPrefs(); - } - - @Override - public void destroy() { - unregisterEventListener(MESSAGE_ZOOM_RECT); - unregisterEventListener(MESSAGE_ZOOM_PAGE); - unregisterEventListener(MESSAGE_TOUCH_LISTENER); - mSubscroller.destroy(); - mTouchEventHandler.destroy(); - } - - private final static float easeOut(float t) { - // ease-out approx. - // -(t-1)^2+1 - t = t-1; - return -t*t+1; - } - - private void registerEventListener(String event) { - mEventDispatcher.registerEventListener(event, this); - } - - private void unregisterEventListener(String event) { - mEventDispatcher.unregisterEventListener(event, this); - } - - private void setState(PanZoomState state) { - if (state != mState) { - //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PanZoom:StateChange", state.toString())); - mState = state; - - // Let the target know we've finished with it (for now) - if (state == PanZoomState.NOTHING) { - mTarget.panZoomStopped(); - } - } - } - - private ImmutableViewportMetrics getMetrics() { - return mTarget.getViewportMetrics(); - } - - private void checkMainThread() { - if (!ThreadUtils.isOnUiThread()) { - // log with full stack trace - Log.e(LOGTAG, "Uh-oh, we're running on the wrong thread!", new Exception()); - } - } - - @Override - public void handleMessage(String event, JSONObject message) { - try { - if (MESSAGE_ZOOM_RECT.equals(event)) { - float x = (float)message.getDouble("x"); - float y = (float)message.getDouble("y"); - final RectF zoomRect = new RectF(x, y, - x + (float)message.getDouble("w"), - y + (float)message.getDouble("h")); - if (message.optBoolean("animate", true)) { - mTarget.post(new Runnable() { - @Override - public void run() { - animatedZoomTo(zoomRect); - } - }); - } else { - mTarget.setViewportMetrics(getMetricsToZoomTo(zoomRect)); - } - } else if (MESSAGE_ZOOM_PAGE.equals(event)) { - ImmutableViewportMetrics metrics = getMetrics(); - RectF cssPageRect = metrics.getCssPageRect(); - - RectF viewableRect = metrics.getCssViewport(); - float y = viewableRect.top; - // attempt to keep zoom keep focused on the center of the viewport - float newHeight = viewableRect.height() * cssPageRect.width() / viewableRect.width(); - float dh = viewableRect.height() - newHeight; // increase in the height - final RectF r = new RectF(0.0f, - y + dh/2, - cssPageRect.width(), - y + dh/2 + newHeight); - if (message.optBoolean("animate", true)) { - mTarget.post(new Runnable() { - @Override - public void run() { - animatedZoomTo(r); - } - }); - } else { - mTarget.setViewportMetrics(getMetricsToZoomTo(r)); - } - } else if (MESSAGE_TOUCH_LISTENER.equals(event)) { - /*int tabId = message.getInt("tabID"); - final Tab tab = Tabs.getInstance().getTab(tabId); - tab.setHasTouchListeners(true); - mTarget.post(new Runnable() { - @Override - public void run() { - if (Tabs.getInstance().isSelectedTab(tab)) - mTouchEventHandler.setWaitForTouchListeners(true); - } - });*/ - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e); - } - } - - /** This function MUST be called on the UI thread */ - @Override - public boolean onKeyEvent(KeyEvent event) { - if (Build.VERSION.SDK_INT <= 11) { - return false; - } - - if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD - && event.getAction() == KeyEvent.ACTION_DOWN) { - - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_ZOOM_IN: - return animatedScale(0.2f); - case KeyEvent.KEYCODE_ZOOM_OUT: - return animatedScale(-0.2f); - } - } - return false; - } - - /** This function MUST be called on the UI thread */ - @Override - public boolean onMotionEvent(MotionEvent event) { - if (Build.VERSION.SDK_INT <= 11) { - return false; - } - - switch (event.getSource() & InputDevice.SOURCE_CLASS_MASK) { - case InputDevice.SOURCE_CLASS_POINTER: - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_SCROLL: return handlePointerScroll(event); - } - break; - case InputDevice.SOURCE_CLASS_JOYSTICK: - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_MOVE: return handleJoystickNav(event); - } - break; - } - return false; - } - - /** This function MUST be called on the UI thread */ - @Override - public boolean onTouchEvent(MotionEvent event) { - return mTouchEventHandler.handleEvent(event); - } - - boolean handleEvent(MotionEvent event, boolean defaultPrevented) { - mDefaultPrevented = defaultPrevented; - - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: return handleTouchStart(event); - case MotionEvent.ACTION_MOVE: return handleTouchMove(event); - case MotionEvent.ACTION_UP: return handleTouchEnd(event); - case MotionEvent.ACTION_CANCEL: return handleTouchCancel(event); - } - return false; - } - - /** This function MUST be called on the UI thread */ - @Override - public void notifyDefaultActionPrevented(boolean prevented) { - mTouchEventHandler.handleEventListenerAction(!prevented); - } - - /** This function must be called from the UI thread. */ - @Override - public void abortAnimation() { - checkMainThread(); - // this happens when gecko changes the viewport on us or if the device is rotated. - // if that's the case, abort any animation in progress and re-zoom so that the page - // snaps to edges. for other cases (where the user's finger(s) are down) don't do - // anything special. - switch (mState) { - case FLING: - mX.stopFling(); - mY.stopFling(); - // fall through - case BOUNCE: - case ANIMATED_ZOOM: - // the zoom that's in progress likely makes no sense any more (such as if - // the screen orientation changed) so abort it - setState(PanZoomState.NOTHING); - // fall through - case NOTHING: - // Don't do animations here; they're distracting and can cause flashes on page - // transitions. - synchronized (mTarget.getLock()) { - mTarget.setViewportMetrics(getValidViewportMetrics()); - mTarget.forceRedraw(null); - } - break; - } - } - - /** This function must be called on the UI thread. */ - public void startingNewEventBlock(MotionEvent event, boolean waitingForTouchListeners) { - checkMainThread(); - mSubscroller.cancel(); - if (waitingForTouchListeners && (event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) { - // this is the first touch point going down, so we enter the pending state - // seting the state will kill any animations in progress, possibly leaving - // the page in overscroll - setState(PanZoomState.WAITING_LISTENERS); - } - } - - /** This must be called on the UI thread. */ - @Override - public void pageRectUpdated() { - if (mState == PanZoomState.NOTHING) { - synchronized (mTarget.getLock()) { - ImmutableViewportMetrics validated = getValidViewportMetrics(); - if (!getMetrics().fuzzyEquals(validated)) { - // page size changed such that we are now in overscroll. snap to the - // the nearest valid viewport - mTarget.setViewportMetrics(validated); - } - } - } - } - - /* - * Panning/scrolling - */ - - private boolean handleTouchStart(MotionEvent event) { - // user is taking control of movement, so stop - // any auto-movement we have going - stopAnimationTask(); - - switch (mState) { - case ANIMATED_ZOOM: - // We just interrupted a double-tap animation, so force a redraw in - // case this touchstart is just a tap that doesn't end up triggering - // a redraw - mTarget.forceRedraw(null); - // fall through - case FLING: - case AUTONAV: - case BOUNCE: - case NOTHING: - case WAITING_LISTENERS: - startTouch(event.getX(0), event.getY(0), event.getEventTime()); - return false; - case TOUCHING: - case PANNING: - case PANNING_LOCKED_X: - case PANNING_LOCKED_Y: - case PANNING_HOLD: - case PANNING_HOLD_LOCKED_X: - case PANNING_HOLD_LOCKED_Y: - case PINCHING: - Log.e(LOGTAG, "Received impossible touch down while in " + mState); - return false; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchStart"); - return false; - } - - private boolean handleTouchMove(MotionEvent event) { - - switch (mState) { - case FLING: - case AUTONAV: - case BOUNCE: - case WAITING_LISTENERS: - // should never happen - Log.e(LOGTAG, "Received impossible touch move while in " + mState); - // fall through - case ANIMATED_ZOOM: - case NOTHING: - // may happen if user double-taps and drags without lifting after the - // second tap. ignore the move if this happens. - return false; - - case TOUCHING: - // Don't allow panning if there is an element in full-screen mode. See bug 775511. - if ((mTarget.isFullScreen() && !mSubscroller.scrolling()) || panDistance(event) < PAN_THRESHOLD) { - return false; - } - cancelTouch(); - startPanning(event.getX(0), event.getY(0), event.getEventTime()); - track(event); - return true; - - case PANNING_HOLD_LOCKED_X: - setState(PanZoomState.PANNING_LOCKED_X); - track(event); - return true; - case PANNING_HOLD_LOCKED_Y: - setState(PanZoomState.PANNING_LOCKED_Y); - // fall through - case PANNING_LOCKED_X: - case PANNING_LOCKED_Y: - track(event); - return true; - - case PANNING_HOLD: - setState(PanZoomState.PANNING); - // fall through - case PANNING: - track(event); - return true; - - case PINCHING: - // scale gesture listener will handle this - return false; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchMove"); - return false; - } - - private boolean handleTouchEnd(MotionEvent event) { - - switch (mState) { - case FLING: - case AUTONAV: - case BOUNCE: - case ANIMATED_ZOOM: - case NOTHING: - // may happen if user double-taps and drags without lifting after the - // second tap. ignore if this happens. - return false; - - case WAITING_LISTENERS: - if (!mDefaultPrevented) { - // should never happen - Log.e(LOGTAG, "Received impossible touch end while in " + mState); - } - // fall through - case TOUCHING: - // the switch into TOUCHING might have happened while the page was - // snapping back after overscroll. we need to finish the snap if that - // was the case - bounce(); - return false; - - case PANNING: - case PANNING_LOCKED_X: - case PANNING_LOCKED_Y: - case PANNING_HOLD: - case PANNING_HOLD_LOCKED_X: - case PANNING_HOLD_LOCKED_Y: - setState(PanZoomState.FLING); - fling(); - return true; - - case PINCHING: - setState(PanZoomState.NOTHING); - return true; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in handleTouchEnd"); - return false; - } - - private boolean handleTouchCancel(MotionEvent event) { - cancelTouch(); - - // ensure we snap back if we're overscrolled - bounce(); - return false; - } - - private boolean handlePointerScroll(MotionEvent event) { - if (mState == PanZoomState.NOTHING || mState == PanZoomState.FLING) { - float scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL); - float scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL); - if (mNegateWheelScrollY) { - scrollY *= -1.0; - } - scrollBy(scrollX * MAX_SCROLL, scrollY * MAX_SCROLL); - bounce(); - return true; - } - return false; - } - - private float filterDeadZone(MotionEvent event, int axis) { - return 0; //(GamepadUtils.isValueInDeadZone(event, axis) ? 0 : event.getAxisValue(axis)); - } - - private float normalizeJoystickScroll(MotionEvent event, int axis) { - return filterDeadZone(event, axis) * MAX_SCROLL; - } - - private float normalizeJoystickZoom(MotionEvent event, int axis) { - // negate MAX_ZOOM_DELTA so that pushing up on the stick zooms in - return filterDeadZone(event, axis) * -MAX_ZOOM_DELTA; - } - - // Since this event is a position-based event rather than a motion-based event, we need to - // set up an AUTONAV animation to keep scrolling even while we don't get events. - private boolean handleJoystickNav(MotionEvent event) { - float velocityX = normalizeJoystickScroll(event, MotionEvent.AXIS_X); - float velocityY = normalizeJoystickScroll(event, MotionEvent.AXIS_Y); - float zoomDelta = normalizeJoystickZoom(event, MotionEvent.AXIS_RZ); - - if (velocityX == 0 && velocityY == 0 && zoomDelta == 0) { - if (mState == PanZoomState.AUTONAV) { - bounce(); // if not needed, this will automatically go to state NOTHING - return true; - } - return false; - } - - if (mState == PanZoomState.NOTHING) { - setState(PanZoomState.AUTONAV); - startAnimationRenderTask(new AutonavRenderTask()); - } - if (mState == PanZoomState.AUTONAV) { - mX.setAutoscrollVelocity(velocityX); - mY.setAutoscrollVelocity(velocityY); - mAutonavZoomDelta = zoomDelta; - return true; - } - return false; - } - - private void startTouch(float x, float y, long time) { - mX.startTouch(x); - mY.startTouch(y); - setState(PanZoomState.TOUCHING); - mLastEventTime = time; - } - - private void startPanning(float x, float y, long time) { - float dx = mX.panDistance(x); - float dy = mY.panDistance(y); - double angle = Math.atan2(dy, dx); // range [-pi, pi] - angle = Math.abs(angle); // range [0, pi] - - // When the touch move breaks through the pan threshold, reposition the touch down origin - // so the page won't jump when we start panning. - mX.startTouch(x); - mY.startTouch(y); - mLastEventTime = time; - - if (mMode == AxisLockMode.STANDARD || mMode == AxisLockMode.STICKY) { - if (!mX.scrollable() || !mY.scrollable()) { - setState(PanZoomState.PANNING); - } else if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) { - mY.setScrollingDisabled(true); - setState(PanZoomState.PANNING_LOCKED_X); - } else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) { - mX.setScrollingDisabled(true); - setState(PanZoomState.PANNING_LOCKED_Y); - } else { - setState(PanZoomState.PANNING); - } - } else if (mMode == AxisLockMode.FREE) { - setState(PanZoomState.PANNING); - } - } - - private float panDistance(MotionEvent move) { - float dx = mX.panDistance(move.getX(0)); - float dy = mY.panDistance(move.getY(0)); - return FloatMath.sqrt(dx * dx + dy * dy); - } - - private void track(float x, float y, long time) { - float timeDelta = (float)(time - mLastEventTime); - if (FloatUtils.fuzzyEquals(timeDelta, 0)) { - // probably a duplicate event, ignore it. using a zero timeDelta will mess - // up our velocity - return; - } - mLastEventTime = time; - - - // if we're axis-locked check if the user is trying to scroll away from the lock - if (mMode == AxisLockMode.STICKY) { - float dx = mX.panDistance(x); - float dy = mY.panDistance(y); - double angle = Math.atan2(dy, dx); // range [-pi, pi] - angle = Math.abs(angle); // range [0, pi] - - if (Math.abs(dx) > AXIS_BREAKOUT_THRESHOLD || Math.abs(dy) > AXIS_BREAKOUT_THRESHOLD) { - if (mState == PanZoomState.PANNING_LOCKED_X) { - if (angle > AXIS_BREAKOUT_ANGLE && angle < (Math.PI - AXIS_BREAKOUT_ANGLE)) { - mY.setScrollingDisabled(false); - setState(PanZoomState.PANNING); - } - } else if (mState == PanZoomState.PANNING_LOCKED_Y) { - if (Math.abs(angle - (Math.PI / 2)) > AXIS_BREAKOUT_ANGLE) { - mX.setScrollingDisabled(false); - setState(PanZoomState.PANNING); - } - } - } - } - - mX.updateWithTouchAt(x, timeDelta); - mY.updateWithTouchAt(y, timeDelta); - } - - private void track(MotionEvent event) { - mX.saveTouchPos(); - mY.saveTouchPos(); - - for (int i = 0; i < event.getHistorySize(); i++) { - track(event.getHistoricalX(0, i), - event.getHistoricalY(0, i), - event.getHistoricalEventTime(i)); - } - track(event.getX(0), event.getY(0), event.getEventTime()); - - if (stopped()) { - if (mState == PanZoomState.PANNING) { - setState(PanZoomState.PANNING_HOLD); - } else if (mState == PanZoomState.PANNING_LOCKED_X) { - setState(PanZoomState.PANNING_HOLD_LOCKED_X); - } else if (mState == PanZoomState.PANNING_LOCKED_Y) { - setState(PanZoomState.PANNING_HOLD_LOCKED_Y); - } else { - // should never happen, but handle anyway for robustness - Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track"); - setState(PanZoomState.PANNING_HOLD); - } - } - - mX.startPan(); - mY.startPan(); - updatePosition(); - } - - private void scrollBy(float dx, float dy) { - mTarget.scrollBy(dx, dy); - } - - private void fling() { - updatePosition(); - - stopAnimationTask(); - - boolean stopped = stopped(); - mX.startFling(stopped); - mY.startFling(stopped); - - startAnimationRenderTask(new FlingRenderTask()); - } - - /* Performs a bounce-back animation to the given viewport metrics. */ - private void bounce(ImmutableViewportMetrics metrics, PanZoomState state) { - stopAnimationTask(); - - ImmutableViewportMetrics bounceStartMetrics = getMetrics(); - if (bounceStartMetrics.fuzzyEquals(metrics)) { - setState(PanZoomState.NOTHING); - return; - } - - setState(state); - - // At this point we have already set mState to BOUNCE or ANIMATED_ZOOM, so - // getRedrawHint() is returning false. This means we can safely call - // setAnimationTarget to set the new final display port and not have it get - // clobbered by display ports from intermediate animation frames. - mTarget.setAnimationTarget(metrics); - startAnimationRenderTask(new BounceRenderTask(bounceStartMetrics, metrics)); - } - - /* Performs a bounce-back animation to the nearest valid viewport metrics. */ - private void bounce() { - bounce(getValidViewportMetrics(), PanZoomState.BOUNCE); - } - - /* Starts the fling or bounce animation. */ - private void startAnimationRenderTask(final PanZoomRenderTask task) { - if (mAnimationRenderTask != null) { - Log.e(LOGTAG, "Attempted to start a new task without canceling the old one!"); - stopAnimationTask(); - } - - mAnimationRenderTask = task; - mTarget.postRenderTask(mAnimationRenderTask); - } - - /* Stops the fling or bounce animation. */ - private void stopAnimationTask() { - if (mAnimationRenderTask != null) { - mAnimationRenderTask.terminate(); - mTarget.removeRenderTask(mAnimationRenderTask); - mAnimationRenderTask = null; - } - } - - private float getVelocity() { - float xvel = mX.getRealVelocity(); - float yvel = mY.getRealVelocity(); - return FloatMath.sqrt(xvel * xvel + yvel * yvel); - } - - @Override - public PointF getVelocityVector() { - return new PointF(mX.getRealVelocity(), mY.getRealVelocity()); - } - - private boolean stopped() { - return getVelocity() < STOPPED_THRESHOLD; - } - - PointF resetDisplacement() { - return new PointF(mX.resetDisplacement(), mY.resetDisplacement()); - } - - private void updatePosition() { - mX.displace(); - mY.displace(); - PointF displacement = resetDisplacement(); - if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) { - return; - } - if (mDefaultPrevented || mSubscroller.scrollBy(displacement)) { - synchronized (mTarget.getLock()) { - mTarget.scrollMarginsBy(displacement.x, displacement.y); - } - } else { - synchronized (mTarget.getLock()) { - scrollBy(displacement.x, displacement.y); - } - } - } - - /** - * This class is an implementation of RenderTask which enforces its implementor to run in the UI thread. - * - */ - private abstract class PanZoomRenderTask extends RenderTask { - - /** - * the time when the current frame was started in ns. - */ - protected long mCurrentFrameStartTime; - /** - * The current frame duration in ns. - */ - protected long mLastFrameTimeDelta; - - private final Runnable mRunnable = new Runnable() { - @Override - public final void run() { - if (mContinueAnimation) { - animateFrame(); - } - } - }; - - private boolean mContinueAnimation = true; - - public PanZoomRenderTask() { - super(false); - } - - @Override - protected final boolean internalRun(long timeDelta, long currentFrameStartTime) { - - mCurrentFrameStartTime = currentFrameStartTime; - mLastFrameTimeDelta = timeDelta; - - mTarget.post(mRunnable); - return mContinueAnimation; - } - - /** - * The method subclasses must override. This method is run on the UI thread thanks to internalRun - */ - protected abstract void animateFrame(); - - /** - * Terminate the animation. - */ - public void terminate() { - mContinueAnimation = false; - } - } - - private class AutonavRenderTask extends PanZoomRenderTask { - public AutonavRenderTask() { - super(); - } - - @Override - protected void animateFrame() { - if (mState != PanZoomState.AUTONAV) { - finishAnimation(); - return; - } - - updatePosition(); - synchronized (mTarget.getLock()) { - mTarget.setViewportMetrics(applyZoomDelta(getMetrics(), mAutonavZoomDelta)); - } - } - } - - /* The task that performs the bounce animation. */ - private class BounceRenderTask extends PanZoomRenderTask { - - /* - * The viewport metrics that represent the start and end of the bounce-back animation, - * respectively. - */ - private ImmutableViewportMetrics mBounceStartMetrics; - private ImmutableViewportMetrics mBounceEndMetrics; - // How long ago this bounce was started in ns. - private long mBounceDuration; - - BounceRenderTask(ImmutableViewportMetrics startMetrics, ImmutableViewportMetrics endMetrics) { - super(); - mBounceStartMetrics = startMetrics; - mBounceEndMetrics = endMetrics; - } - - @Override - protected void animateFrame() { - /* - * The pan/zoom controller might have signaled to us that it wants to abort the - * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail - * out. - */ - if (!(mState == PanZoomState.BOUNCE || mState == PanZoomState.ANIMATED_ZOOM)) { - finishAnimation(); - return; - } - - /* Perform the next frame of the bounce-back animation. */ - mBounceDuration = mCurrentFrameStartTime - getStartTime(); - if (mBounceDuration < BOUNCE_ANIMATION_DURATION) { - advanceBounce(); - return; - } - - /* Finally, if there's nothing else to do, complete the animation and go to sleep. */ - finishBounce(); - finishAnimation(); - setState(PanZoomState.NOTHING); - } - - /* Performs one frame of a bounce animation. */ - private void advanceBounce() { - synchronized (mTarget.getLock()) { - float t = easeOut((float)mBounceDuration / BOUNCE_ANIMATION_DURATION); - ImmutableViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t); - mTarget.setViewportMetrics(newMetrics); - } - } - - /* Concludes a bounce animation and snaps the viewport into place. */ - private void finishBounce() { - synchronized (mTarget.getLock()) { - mTarget.setViewportMetrics(mBounceEndMetrics); - } - } - } - - // The callback that performs the fling animation. - private class FlingRenderTask extends PanZoomRenderTask { - - public FlingRenderTask() { - super(); - } - - @Override - protected void animateFrame() { - /* - * The pan/zoom controller might have signaled to us that it wants to abort the - * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail - * out. - */ - if (mState != PanZoomState.FLING) { - finishAnimation(); - return; - } - - /* Advance flings, if necessary. */ - boolean flingingX = mX.advanceFling(mLastFrameTimeDelta); - boolean flingingY = mY.advanceFling(mLastFrameTimeDelta); - - boolean overscrolled = (mX.overscrolled() || mY.overscrolled()); - - /* If we're still flinging in any direction, update the origin. */ - if (flingingX || flingingY) { - updatePosition(); - - /* - * Check to see if we're still flinging with an appreciable velocity. The threshold is - * higher in the case of overscroll, so we bounce back eagerly when overscrolling but - * coast smoothly to a stop when not. In other words, require a greater velocity to - * maintain the fling once we enter overscroll. - */ - float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD); - if (getVelocity() >= threshold) { - // we're still flinging - return; - } - - mX.stopFling(); - mY.stopFling(); - } - - /* Perform a bounce-back animation if overscrolled. */ - if (overscrolled) { - bounce(); - } else { - finishAnimation(); - setState(PanZoomState.NOTHING); - } - } - } - - private void finishAnimation() { - checkMainThread(); - - stopAnimationTask(); - - // Force a viewport synchronisation - mTarget.forceRedraw(null); - } - - /* Returns the nearest viewport metrics with no overscroll visible. */ - private ImmutableViewportMetrics getValidViewportMetrics() { - return getValidViewportMetrics(getMetrics()); - } - - private ImmutableViewportMetrics getValidViewportMetrics(ImmutableViewportMetrics viewportMetrics) { - /* First, we adjust the zoom factor so that we can make no overscrolled area visible. */ - float zoomFactor = viewportMetrics.zoomFactor; - RectF pageRect = viewportMetrics.getPageRect(); - RectF viewport = viewportMetrics.getViewport(); - - float focusX = viewport.width() / 2.0f; - float focusY = viewport.height() / 2.0f; - - float minZoomFactor = 0.0f; - float maxZoomFactor = MAX_ZOOM; - - ZoomConstraints constraints = mTarget.getZoomConstraints(); - - if (constraints.getMinZoom() > 0) - minZoomFactor = constraints.getMinZoom(); - if (constraints.getMaxZoom() > 0) - maxZoomFactor = constraints.getMaxZoom(); - - if (!constraints.getAllowZoom()) { - // If allowZoom is false, clamp to the default zoom level. - maxZoomFactor = minZoomFactor = constraints.getDefaultZoom(); - } - - // Ensure minZoomFactor keeps the page at least as big as the viewport. - if (pageRect.width() > 0) { - float pageWidth = pageRect.width() + - viewportMetrics.marginLeft + - viewportMetrics.marginRight; - float scaleFactor = viewport.width() / pageWidth; - minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor); - if (viewport.width() > pageWidth) - focusX = 0.0f; - } - if (pageRect.height() > 0) { - float pageHeight = pageRect.height() + - viewportMetrics.marginTop + - viewportMetrics.marginBottom; - float scaleFactor = viewport.height() / pageHeight; - minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor); - if (viewport.height() > pageHeight) - focusY = 0.0f; - } - - maxZoomFactor = Math.max(maxZoomFactor, minZoomFactor); - - if (zoomFactor < minZoomFactor) { - // if one (or both) of the page dimensions is smaller than the viewport, - // zoom using the top/left as the focus on that axis. this prevents the - // scenario where, if both dimensions are smaller than the viewport, but - // by different scale factors, we end up scrolled to the end on one axis - // after applying the scale - PointF center = new PointF(focusX, focusY); - viewportMetrics = viewportMetrics.scaleTo(minZoomFactor, center); - } else if (zoomFactor > maxZoomFactor) { - PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f); - viewportMetrics = viewportMetrics.scaleTo(maxZoomFactor, center); - } - - /* Now we pan to the right origin. */ - viewportMetrics = viewportMetrics.clampWithMargins(); - - return viewportMetrics; - } - - private class AxisX extends Axis { - AxisX(SubdocumentScrollHelper subscroller) { super(subscroller); } - @Override - public float getOrigin() { return getMetrics().viewportRectLeft; } - @Override - protected float getViewportLength() { return getMetrics().getWidth(); } - @Override - protected float getPageStart() { return getMetrics().pageRectLeft; } - @Override - protected float getMarginStart() { return mTarget.getMaxMargins().left - getMetrics().marginLeft; } - @Override - protected float getMarginEnd() { return mTarget.getMaxMargins().right - getMetrics().marginRight; } - @Override - protected float getPageLength() { return getMetrics().getPageWidthWithMargins(); } - @Override - protected boolean marginsHidden() { - ImmutableViewportMetrics metrics = getMetrics(); - RectF maxMargins = mTarget.getMaxMargins(); - return (metrics.marginLeft < maxMargins.left || metrics.marginRight < maxMargins.right); - } - @Override - protected void overscrollFling(final float velocity) { - if (mOverscroll != null) { - mOverscroll.setVelocity(velocity, Overscroll.Axis.X); - } - } - @Override - protected void overscrollPan(final float distance) { - if (mOverscroll != null) { - mOverscroll.setDistance(distance, Overscroll.Axis.X); - } - } - } - - private class AxisY extends Axis { - AxisY(SubdocumentScrollHelper subscroller) { super(subscroller); } - @Override - public float getOrigin() { return getMetrics().viewportRectTop; } - @Override - protected float getViewportLength() { return getMetrics().getHeight(); } - @Override - protected float getPageStart() { return getMetrics().pageRectTop; } - @Override - protected float getPageLength() { return getMetrics().getPageHeightWithMargins(); } - @Override - protected float getMarginStart() { return mTarget.getMaxMargins().top - getMetrics().marginTop; } - @Override - protected float getMarginEnd() { return mTarget.getMaxMargins().bottom - getMetrics().marginBottom; } - @Override - protected boolean marginsHidden() { - ImmutableViewportMetrics metrics = getMetrics(); - RectF maxMargins = mTarget.getMaxMargins(); - return (metrics.marginTop < maxMargins.top || metrics.marginBottom < maxMargins.bottom); - } - @Override - protected void overscrollFling(final float velocity) { - if (mOverscroll != null) { - mOverscroll.setVelocity(velocity, Overscroll.Axis.Y); - } - } - @Override - protected void overscrollPan(final float distance) { - if (mOverscroll != null) { - mOverscroll.setDistance(distance, Overscroll.Axis.Y); - } - } - } - - /* - * Zooming - */ - @Override - public boolean onScaleBegin(SimpleScaleGestureDetector detector) { - if (mState == PanZoomState.ANIMATED_ZOOM) - return false; - - if (!mTarget.getZoomConstraints().getAllowZoom()) - return false; - - setState(PanZoomState.PINCHING); - mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY()); - cancelTouch(); - - //GeckoAppShell.sendEventToGecko(GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_START, mLastZoomFocus, getMetrics().zoomFactor)); - - return true; - } - - @Override - public boolean onScale(SimpleScaleGestureDetector detector) { - if (mTarget.isFullScreen()) - return false; - - if (mState != PanZoomState.PINCHING) - return false; - - float prevSpan = detector.getPreviousSpan(); - if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) { - // let's eat this one to avoid setting the new zoom to infinity (bug 711453) - return true; - } - - synchronized (mTarget.getLock()) { - float zoomFactor = getAdjustedZoomFactor(detector.getCurrentSpan() / prevSpan); - scrollBy(mLastZoomFocus.x - detector.getFocusX(), - mLastZoomFocus.y - detector.getFocusY()); - mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY()); - ImmutableViewportMetrics target = getMetrics().scaleTo(zoomFactor, mLastZoomFocus); - - // If overscroll is diabled, prevent zooming outside the normal document pans. - if (mX.getOverScrollMode() == View.OVER_SCROLL_NEVER || mY.getOverScrollMode() == View.OVER_SCROLL_NEVER) { - target = getValidViewportMetrics(target); - } - mTarget.setViewportMetrics(target); - } - - //GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY, mLastZoomFocus, getMetrics().zoomFactor); - //GeckoAppShell.sendEventToGecko(event); - - return true; - } - - private ImmutableViewportMetrics applyZoomDelta(ImmutableViewportMetrics metrics, float zoomDelta) { - float oldZoom = metrics.zoomFactor; - float newZoom = oldZoom + zoomDelta; - float adjustedZoom = getAdjustedZoomFactor(newZoom / oldZoom); - // since we don't have a particular focus to zoom to, just use the center - PointF center = new PointF(metrics.getWidth() / 2.0f, metrics.getHeight() / 2.0f); - metrics = metrics.scaleTo(adjustedZoom, center); - return metrics; - } - - private boolean animatedScale(float zoomDelta) { - if (mState != PanZoomState.NOTHING && mState != PanZoomState.BOUNCE) { - return false; - } - synchronized (mTarget.getLock()) { - ImmutableViewportMetrics metrics = applyZoomDelta(getMetrics(), zoomDelta); - bounce(getValidViewportMetrics(metrics), PanZoomState.BOUNCE); - } - return true; - } - - private float getAdjustedZoomFactor(float zoomRatio) { - /* - * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom - * factor toward 1.0. - */ - float resistance = Math.min(mX.getEdgeResistance(true), mY.getEdgeResistance(true)); - if (zoomRatio > 1.0f) - zoomRatio = 1.0f + (zoomRatio - 1.0f) * resistance; - else - zoomRatio = 1.0f - (1.0f - zoomRatio) * resistance; - - float newZoomFactor = getMetrics().zoomFactor * zoomRatio; - float minZoomFactor = 0.0f; - float maxZoomFactor = MAX_ZOOM; - - ZoomConstraints constraints = mTarget.getZoomConstraints(); - - if (constraints.getMinZoom() > 0) - minZoomFactor = constraints.getMinZoom(); - if (constraints.getMaxZoom() > 0) - maxZoomFactor = constraints.getMaxZoom(); - - if (newZoomFactor < minZoomFactor) { - // apply resistance when zooming past minZoomFactor, - // such that it asymptotically reaches minZoomFactor / 2.0 - // but never exceeds that - final float rate = 0.5f; // controls how quickly we approach the limit - float excessZoom = minZoomFactor - newZoomFactor; - excessZoom = 1.0f - (float)Math.exp(-excessZoom * rate); - newZoomFactor = minZoomFactor * (1.0f - excessZoom / 2.0f); - } - - if (newZoomFactor > maxZoomFactor) { - // apply resistance when zooming past maxZoomFactor, - // such that it asymptotically reaches maxZoomFactor + 1.0 - // but never exceeds that - float excessZoom = newZoomFactor - maxZoomFactor; - excessZoom = 1.0f - (float)Math.exp(-excessZoom); - newZoomFactor = maxZoomFactor + excessZoom; - } - - return newZoomFactor; - } - - @Override - public void onScaleEnd(SimpleScaleGestureDetector detector) { - if (mState == PanZoomState.ANIMATED_ZOOM) - return; - - // switch back to the touching state - startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime()); - - // Force a viewport synchronisation - mTarget.forceRedraw(null); - - PointF point = new PointF(detector.getFocusX(), detector.getFocusY()); - //GeckoEvent event = GeckoEvent.createNativeGestureEvent(GeckoEvent.ACTION_MAGNIFY_END, point, getMetrics().zoomFactor); - - //if (event == null) { - // return; - //} - - //GeckoAppShell.sendEventToGecko(event); - } - - @Override - public boolean getRedrawHint() { - switch (mState) { - case PINCHING: - case ANIMATED_ZOOM: - case BOUNCE: - // don't redraw during these because the zoom is (or might be, in the case - // of BOUNCE) be changing rapidly and gecko will have to redraw the entire - // display port area. we trigger a force-redraw upon exiting these states. - return false; - default: - // allow redrawing in other states - return true; - } - } - - private void sendPointToGecko(String event, MotionEvent motionEvent) { - String json; - try { - PointF point = new PointF(motionEvent.getX(), motionEvent.getY()); - point = mTarget.convertViewPointToLayerPoint(point); - if (point == null) { - return; - } - json = PointUtils.toJSON(point).toString(); - } catch (Exception e) { - Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e); - return; - } - - //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json)); - } - - @Override - public boolean onDown(MotionEvent motionEvent) { - mMediumPress = false; - return false; - } - - @Override - public void onShowPress(MotionEvent motionEvent) { - // If we get this, it will be followed either by a call to - // onSingleTapUp (if the user lifts their finger before the - // long-press timeout) or a call to onLongPress (if the user - // does not). In the former case, we want to make sure it is - // treated as a click. (Note that if this is called, we will - // not get a call to onDoubleTap). - mMediumPress = true; - } - - @Override - public void onLongPress(MotionEvent motionEvent) { - sendPointToGecko("Gesture:LongPress", motionEvent); - } - - @Override - public boolean onSingleTapUp(MotionEvent motionEvent) { - // When zooming is enabled, we wait to see if there's a double-tap. - // However, if mMediumPress is true then we know there will be no - // double-tap so we treat this as a click. - if (mMediumPress || !mTarget.getZoomConstraints().getAllowZoom()) { - sendPointToGecko("Gesture:SingleTap", motionEvent); - } - // return false because we still want to get the ACTION_UP event that triggers this - return false; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent motionEvent) { - // When zooming is disabled, we handle this in onSingleTapUp. - if (mTarget.getZoomConstraints().getAllowZoom()) { - sendPointToGecko("Gesture:SingleTap", motionEvent); - } - return true; - } - - @Override - public boolean onDoubleTap(MotionEvent motionEvent) { - if (mTarget.getZoomConstraints().getAllowZoom()) { - sendPointToGecko("Gesture:DoubleTap", motionEvent); - } - return true; - } - - private void cancelTouch() { - //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", ""); - //GeckoAppShell.sendEventToGecko(e); - } - - /** - * Zoom to a specified rect IN CSS PIXELS. - * - * While we usually use device pixels, @zoomToRect must be specified in CSS - * pixels. - */ - private ImmutableViewportMetrics getMetricsToZoomTo(RectF zoomToRect) { - final float startZoom = getMetrics().zoomFactor; - - RectF viewport = getMetrics().getViewport(); - // 1. adjust the aspect ratio of zoomToRect to match that of the current viewport, - // enlarging as necessary (if it gets too big, it will get shrunk in the next step). - // while enlarging make sure we enlarge equally on both sides to keep the target rect - // centered. - float targetRatio = viewport.width() / viewport.height(); - float rectRatio = zoomToRect.width() / zoomToRect.height(); - if (FloatUtils.fuzzyEquals(targetRatio, rectRatio)) { - // all good, do nothing - } else if (targetRatio < rectRatio) { - // need to increase zoomToRect height - float newHeight = zoomToRect.width() / targetRatio; - zoomToRect.top -= (newHeight - zoomToRect.height()) / 2; - zoomToRect.bottom = zoomToRect.top + newHeight; - } else { // targetRatio > rectRatio) { - // need to increase zoomToRect width - float newWidth = targetRatio * zoomToRect.height(); - zoomToRect.left -= (newWidth - zoomToRect.width()) / 2; - zoomToRect.right = zoomToRect.left + newWidth; - } - - float finalZoom = viewport.width() / zoomToRect.width(); - - ImmutableViewportMetrics finalMetrics = getMetrics(); - finalMetrics = finalMetrics.setViewportOrigin( - zoomToRect.left * finalMetrics.zoomFactor, - zoomToRect.top * finalMetrics.zoomFactor); - finalMetrics = finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f)); - - // 2. now run getValidViewportMetrics on it, so that the target viewport is - // clamped down to prevent overscroll, over-zoom, and other bad conditions. - finalMetrics = getValidViewportMetrics(finalMetrics); - return finalMetrics; - } - - private boolean animatedZoomTo(RectF zoomToRect) { - bounce(getMetricsToZoomTo(zoomToRect), PanZoomState.ANIMATED_ZOOM); - return true; - } - - /** This function must be called from the UI thread. */ - @Override - public void abortPanning() { - checkMainThread(); - bounce(); - } - - @Override - public void setOverScrollMode(int overscrollMode) { - mX.setOverScrollMode(overscrollMode); - mY.setOverScrollMode(overscrollMode); - } - - @Override - public int getOverScrollMode() { - return mX.getOverScrollMode(); - } - - @Override - public void setOverscrollHandler(final Overscroll handler) { - mOverscroll = handler; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java deleted file mode 100644 index cae7377d7a29..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Layer.java +++ /dev/null @@ -1,207 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.FloatUtils; - -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; - -import java.nio.FloatBuffer; -import java.util.concurrent.locks.ReentrantLock; - -public abstract class Layer { - private final ReentrantLock mTransactionLock; - private boolean mInTransaction; - private Rect mNewPosition; - private float mNewResolution; - - protected Rect mPosition; - protected float mResolution; - - public Layer() { - this(null); - } - - public Layer(IntSize size) { - mTransactionLock = new ReentrantLock(); - if (size == null) { - mPosition = new Rect(); - } else { - mPosition = new Rect(0, 0, size.width, size.height); - } - mResolution = 1.0f; - } - - /** - * Updates the layer. This returns false if there is still work to be done - * after this update. - */ - public final boolean update(RenderContext context) { - if (mTransactionLock.isHeldByCurrentThread()) { - throw new RuntimeException("draw() called while transaction lock held by this " + - "thread?!"); - } - - if (mTransactionLock.tryLock()) { - try { - performUpdates(context); - return true; - } finally { - mTransactionLock.unlock(); - } - } - - return false; - } - - /** Subclasses override this function to draw the layer. */ - public abstract void draw(RenderContext context); - - /** Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect. */ - protected RectF getBounds(RenderContext context) { - return RectUtils.scale(new RectF(mPosition), context.zoomFactor / mResolution); - } - - /** - * Call this before modifying the layer. Note that, for TileLayers, "modifying the layer" - * includes altering the underlying CairoImage in any way. Thus you must call this function - * before modifying the byte buffer associated with this layer. - * - * This function may block, so you should never call this on the main UI thread. - */ - public void beginTransaction() { - if (mTransactionLock.isHeldByCurrentThread()) - throw new RuntimeException("Nested transactions are not supported"); - mTransactionLock.lock(); - mInTransaction = true; - mNewResolution = mResolution; - } - - /** Call this when you're done modifying the layer. */ - public void endTransaction() { - if (!mInTransaction) - throw new RuntimeException("endTransaction() called outside a transaction"); - mInTransaction = false; - mTransactionLock.unlock(); - } - - /** Returns true if the layer is currently in a transaction and false otherwise. */ - protected boolean inTransaction() { - return mInTransaction; - } - - /** Returns the current layer position. */ - public Rect getPosition() { - return mPosition; - } - - /** Sets the position. Only valid inside a transaction. */ - public void setPosition(Rect newPosition) { - if (!mInTransaction) - throw new RuntimeException("setPosition() is only valid inside a transaction"); - mNewPosition = newPosition; - } - - /** Returns the current layer's resolution. */ - public float getResolution() { - return mResolution; - } - - /** - * Sets the layer resolution. This value is used to determine how many pixels per - * device pixel this layer was rendered at. This will be reflected by scaling by - * the reciprocal of the resolution in the layer's transform() function. - * Only valid inside a transaction. */ - public void setResolution(float newResolution) { - if (!mInTransaction) - throw new RuntimeException("setResolution() is only valid inside a transaction"); - mNewResolution = newResolution; - } - - /** - * Subclasses may override this method to perform custom layer updates. This will be called - * with the transaction lock held. Subclass implementations of this method must call the - * superclass implementation. Returns false if there is still work to be done after this - * update is complete. - */ - protected void performUpdates(RenderContext context) { - if (mNewPosition != null) { - mPosition = mNewPosition; - mNewPosition = null; - } - if (mNewResolution != 0.0f) { - mResolution = mNewResolution; - mNewResolution = 0.0f; - } - } - - /** - * This function fills in the provided dest array with values to render a texture. - * The array is filled with 4 sets of {x, y, z, texture_x, texture_y} values (so 20 values - * in total) corresponding to the corners of the rect. - */ - protected final void fillRectCoordBuffer(float[] dest, RectF rect, float viewWidth, float viewHeight, - Rect cropRect, float texWidth, float texHeight) { - //x, y, z, texture_x, texture_y - dest[0] = rect.left / viewWidth; - dest[1] = rect.bottom / viewHeight; - dest[2] = 0; - dest[3] = cropRect.left / texWidth; - dest[4] = cropRect.top / texHeight; - - dest[5] = rect.left / viewWidth; - dest[6] = rect.top / viewHeight; - dest[7] = 0; - dest[8] = cropRect.left / texWidth; - dest[9] = cropRect.bottom / texHeight; - - dest[10] = rect.right / viewWidth; - dest[11] = rect.bottom / viewHeight; - dest[12] = 0; - dest[13] = cropRect.right / texWidth; - dest[14] = cropRect.top / texHeight; - - dest[15] = rect.right / viewWidth; - dest[16] = rect.top / viewHeight; - dest[17] = 0; - dest[18] = cropRect.right / texWidth; - dest[19] = cropRect.bottom / texHeight; - } - - public static class RenderContext { - public final RectF viewport; - public final RectF pageRect; - public final float zoomFactor; - public final PointF offset; - public final int positionHandle; - public final int textureHandle; - public final FloatBuffer coordBuffer; - - public RenderContext(RectF aViewport, RectF aPageRect, float aZoomFactor, PointF aOffset, - int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) { - viewport = aViewport; - pageRect = aPageRect; - zoomFactor = aZoomFactor; - offset = aOffset; - positionHandle = aPositionHandle; - textureHandle = aTextureHandle; - coordBuffer = aCoordBuffer; - } - - public boolean fuzzyEquals(RenderContext other) { - if (other == null) { - return false; - } - return RectUtils.fuzzyEquals(viewport, other.viewport) - && RectUtils.fuzzyEquals(pageRect, other.pageRect) - && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor) - && FloatUtils.fuzzyEquals(offset, other.offset); - } - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java deleted file mode 100644 index c2b719b914dc..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerMarginsAnimator.java +++ /dev/null @@ -1,324 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -//import org.mozilla.gecko.PrefsHelper; -import org.mozilla.gecko.TouchEventInterceptor; -import org.mozilla.gecko.util.FloatUtils; -import org.mozilla.gecko.util.ThreadUtils; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.os.SystemClock; -import android.util.Log; -import android.view.animation.DecelerateInterpolator; -import android.view.MotionEvent; -import android.view.View; - -public class LayerMarginsAnimator implements TouchEventInterceptor { - private static final String LOGTAG = "GeckoLayerMarginsAnimator"; - // The duration of the animation in ns - private static final long MARGIN_ANIMATION_DURATION = 250000000; - private static final String PREF_SHOW_MARGINS_THRESHOLD = "browser.ui.show-margins-threshold"; - - /* This is the proportion of the viewport rect, minus maximum margins, - * that needs to be travelled before margins will be exposed. - */ - private float SHOW_MARGINS_THRESHOLD = 0.20f; - - /* This rect stores the maximum value margins can grow to when scrolling. When writing - * to this member variable, or when reading from this member variable on a non-UI thread, - * you must synchronize on the LayerMarginsAnimator instance. */ - private final RectF mMaxMargins; - /* If this boolean is true, scroll changes will not affect margins */ - private boolean mMarginsPinned; - /* The task that handles showing/hiding margins */ - private LayerMarginsAnimationTask mAnimationTask; - /* This interpolator is used for the above mentioned animation */ - private final DecelerateInterpolator mInterpolator; - /* The GeckoLayerClient whose margins will be animated */ - private final GeckoLayerClient mTarget; - /* The distance that has been scrolled since either the first touch event, - * or since the margins were last fully hidden */ - private final PointF mTouchTravelDistance; - /* The ID of the prefs listener for the show-marginss threshold */ - private Integer mPrefObserverId; - - public LayerMarginsAnimator(GeckoLayerClient aTarget, LayerView aView) { - // Assign member variables from parameters - mTarget = aTarget; - - // Create other member variables - mMaxMargins = new RectF(); - mInterpolator = new DecelerateInterpolator(); - mTouchTravelDistance = new PointF(); - - // Listen to the dynamic toolbar pref - /*mPrefObserverId = PrefsHelper.getPref(PREF_SHOW_MARGINS_THRESHOLD, new PrefsHelper.PrefHandlerBase() { - @Override - public void prefValue(String pref, int value) { - SHOW_MARGINS_THRESHOLD = (float)value / 100.0f; - } - - @Override - public boolean isObserver() { - return true; - } - });*/ - - // Listen to touch events, for auto-pinning - aView.addTouchInterceptor(this); - } - - public void destroy() { - if (mPrefObserverId != null) { - //PrefsHelper.removeObserver(mPrefObserverId); - mPrefObserverId = null; - } - } - - /** - * Sets the maximum values for margins to grow to, in pixels. - */ - public synchronized void setMaxMargins(float left, float top, float right, float bottom) { - ThreadUtils.assertOnUiThread(); - - mMaxMargins.set(left, top, right, bottom); - - // Update the Gecko-side global for fixed viewport margins. - /*GeckoAppShell.sendEventToGecko( - GeckoEvent.createBroadcastEvent("Viewport:FixedMarginsChanged", - "{ \"top\" : " + top + ", \"right\" : " + right - + ", \"bottom\" : " + bottom + ", \"left\" : " + left + " }"));*/ - } - - RectF getMaxMargins() { - return mMaxMargins; - } - - private void animateMargins(final float left, final float top, final float right, final float bottom, boolean immediately) { - if (mAnimationTask != null) { - mTarget.getView().removeRenderTask(mAnimationTask); - mAnimationTask = null; - } - - if (immediately) { - ImmutableViewportMetrics newMetrics = mTarget.getViewportMetrics().setMargins(left, top, right, bottom); - mTarget.forceViewportMetrics(newMetrics, true, true); - return; - } - - ImmutableViewportMetrics metrics = mTarget.getViewportMetrics(); - - mAnimationTask = new LayerMarginsAnimationTask(false, metrics, left, top, right, bottom); - mTarget.getView().postRenderTask(mAnimationTask); - } - - /** - * Exposes the margin area by growing the margin components of the current - * metrics to the values set in setMaxMargins. - */ - public synchronized void showMargins(boolean immediately) { - animateMargins(mMaxMargins.left, mMaxMargins.top, mMaxMargins.right, mMaxMargins.bottom, immediately); - } - - public synchronized void hideMargins(boolean immediately) { - animateMargins(0, 0, 0, 0, immediately); - } - - public void setMarginsPinned(boolean pin) { - if (pin == mMarginsPinned) { - return; - } - - mMarginsPinned = pin; - } - - public boolean areMarginsShown() { - final ImmutableViewportMetrics metrics = mTarget.getViewportMetrics(); - return metrics.marginLeft != 0 || - metrics.marginRight != 0 || - metrics.marginTop != 0 || - metrics.marginBottom != 0; - } - - /** - * This function will scroll a margin down to zero, or up to the maximum - * specified margin size and return the left-over delta. - * aMargins are in/out parameters. In specifies the current margin size, - * and out specifies the modified margin size. They are specified in the - * order of start-margin, then end-margin. - * This function will also take into account how far the touch point has - * moved and react accordingly. If a touch point hasn't moved beyond a - * certain threshold, margins can only be hidden and not shown. - * aNegativeOffset can be used if the remaining delta should be determined - * by the end-margin instead of the start-margin (for example, in rtl - * pages). - */ - private float scrollMargin(float[] aMargins, float aDelta, - float aOverscrollStart, float aOverscrollEnd, - float aTouchTravelDistance, - float aViewportStart, float aViewportEnd, - float aPageStart, float aPageEnd, - float aMaxMarginStart, float aMaxMarginEnd, - boolean aNegativeOffset) { - float marginStart = aMargins[0]; - float marginEnd = aMargins[1]; - float viewportSize = aViewportEnd - aViewportStart; - float exposeThreshold = viewportSize * SHOW_MARGINS_THRESHOLD; - - if (aDelta >= 0) { - float marginDelta = Math.max(0, aDelta - aOverscrollStart); - aMargins[0] = marginStart - Math.min(marginDelta, marginStart); - if (aTouchTravelDistance < exposeThreshold && marginEnd == 0) { - // We only want the margin to be newly exposed after the touch - // has moved a certain distance. - marginDelta = Math.max(0, marginDelta - (aPageEnd - aViewportEnd)); - } - aMargins[1] = marginEnd + Math.min(marginDelta, aMaxMarginEnd - marginEnd); - } else { - float marginDelta = Math.max(0, -aDelta - aOverscrollEnd); - aMargins[1] = marginEnd - Math.min(marginDelta, marginEnd); - if (-aTouchTravelDistance < exposeThreshold && marginStart == 0) { - marginDelta = Math.max(0, marginDelta - (aViewportStart - aPageStart)); - } - aMargins[0] = marginStart + Math.min(marginDelta, aMaxMarginStart - marginStart); - } - - if (aNegativeOffset) { - return aDelta - (marginEnd - aMargins[1]); - } - return aDelta - (marginStart - aMargins[0]); - } - - /* - * Taking maximum margins into account, offsets the margins and then the - * viewport origin and returns the modified metrics. - */ - ImmutableViewportMetrics scrollBy(ImmutableViewportMetrics aMetrics, float aDx, float aDy) { - float[] newMarginsX = { aMetrics.marginLeft, aMetrics.marginRight }; - float[] newMarginsY = { aMetrics.marginTop, aMetrics.marginBottom }; - - // Only alter margins if the toolbar isn't pinned - if (!mMarginsPinned) { - // Make sure to cancel any margin animations when margin-scrolling begins - if (mAnimationTask != null) { - mTarget.getView().removeRenderTask(mAnimationTask); - mAnimationTask = null; - } - - // Reset the touch travel when changing direction - if ((aDx >= 0) != (mTouchTravelDistance.x >= 0)) { - mTouchTravelDistance.x = 0; - } - if ((aDy >= 0) != (mTouchTravelDistance.y >= 0)) { - mTouchTravelDistance.y = 0; - } - - mTouchTravelDistance.offset(aDx, aDy); - RectF overscroll = aMetrics.getOverscroll(); - - // Only allow margins to scroll if the page can fill the viewport. - if (aMetrics.getPageWidth() >= aMetrics.getWidth()) { - aDx = scrollMargin(newMarginsX, aDx, - overscroll.left, overscroll.right, - mTouchTravelDistance.x, - aMetrics.viewportRectLeft, aMetrics.viewportRectRight, - aMetrics.pageRectLeft, aMetrics.pageRectRight, - mMaxMargins.left, mMaxMargins.right, - aMetrics.isRTL); - } - if (aMetrics.getPageHeight() >= aMetrics.getHeight()) { - aDy = scrollMargin(newMarginsY, aDy, - overscroll.top, overscroll.bottom, - mTouchTravelDistance.y, - aMetrics.viewportRectTop, aMetrics.viewportRectBottom, - aMetrics.pageRectTop, aMetrics.pageRectBottom, - mMaxMargins.top, mMaxMargins.bottom, - false); - } - } - - return aMetrics.setMargins(newMarginsX[0], newMarginsY[0], newMarginsX[1], newMarginsY[1]).offsetViewportBy(aDx, aDy); - } - - /** Implementation of TouchEventInterceptor */ - @Override - public boolean onTouch(View view, MotionEvent event) { - return false; - } - - /** Implementation of TouchEventInterceptor */ - @Override - public boolean onInterceptTouchEvent(View view, MotionEvent event) { - int action = event.getActionMasked(); - if (action == MotionEvent.ACTION_DOWN && event.getPointerCount() == 1) { - mTouchTravelDistance.set(0.0f, 0.0f); - } - - return false; - } - - class LayerMarginsAnimationTask extends RenderTask { - private float mStartLeft, mStartTop, mStartRight, mStartBottom; - private float mTop, mBottom, mLeft, mRight; - private boolean mContinueAnimation; - - public LayerMarginsAnimationTask(boolean runAfter, ImmutableViewportMetrics metrics, - float left, float top, float right, float bottom) { - super(runAfter); - mContinueAnimation = true; - this.mStartLeft = metrics.marginLeft; - this.mStartTop = metrics.marginTop; - this.mStartRight = metrics.marginRight; - this.mStartBottom = metrics.marginBottom; - this.mLeft = left; - this.mRight = right; - this.mTop = top; - this.mBottom = bottom; - } - - @Override - public boolean internalRun(long timeDelta, long currentFrameStartTime) { - if (!mContinueAnimation) { - return false; - } - - // Calculate the progress (between 0 and 1) - float progress = mInterpolator.getInterpolation( - Math.min(1.0f, (System.nanoTime() - getStartTime()) - / (float)MARGIN_ANIMATION_DURATION)); - - // Calculate the new metrics accordingly - synchronized (mTarget.getLock()) { - ImmutableViewportMetrics oldMetrics = mTarget.getViewportMetrics(); - ImmutableViewportMetrics newMetrics = oldMetrics.setMargins( - FloatUtils.interpolate(mStartLeft, mLeft, progress), - FloatUtils.interpolate(mStartTop, mTop, progress), - FloatUtils.interpolate(mStartRight, mRight, progress), - FloatUtils.interpolate(mStartBottom, mBottom, progress)); - PointF oldOffset = oldMetrics.getMarginOffset(); - PointF newOffset = newMetrics.getMarginOffset(); - newMetrics = - newMetrics.offsetViewportByAndClamp(newOffset.x - oldOffset.x, - newOffset.y - oldOffset.y); - - if (progress >= 1.0f) { - mContinueAnimation = false; - - // Force a redraw and update Gecko - mTarget.forceViewportMetrics(newMetrics, true, true); - } else { - mTarget.forceViewportMetrics(newMetrics, false, false); - } - } - return mContinueAnimation; - } - } - -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java deleted file mode 100644 index e8759fd3e462..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java +++ /dev/null @@ -1,722 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -import org.libreoffice.R; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.R; -//import org.mozilla.gecko.Tab; -//import org.mozilla.gecko.Tabs; -import org.mozilla.gecko.gfx.Layer.RenderContext; -import org.mozilla.gecko.gfx.RenderTask; -import org.mozilla.gecko.mozglue.DirectBufferAllocator; - -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import android.opengl.GLES20; -import android.os.SystemClock; -import android.util.Log; -//import org.mozilla.gecko.mozglue.JNITarget; - -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.microedition.khronos.egl.EGLConfig; - -/** - * The layer renderer implements the rendering logic for a layer view. - */ -public class LayerRenderer /*implements Tabs.OnTabsChangedListener*/ { - private static final String LOGTAG = "GeckoLayerRenderer"; - private static final String PROFTAG = "GeckoLayerRendererProf"; - - /* - * The amount of time a frame is allowed to take to render before we declare it a dropped - * frame. - */ - private static final int MAX_FRAME_TIME = 16; /* 1000 ms / 60 FPS */ - - private static final int FRAME_RATE_METER_WIDTH = 128; - private static final int FRAME_RATE_METER_HEIGHT = 32; - - private static final long NANOS_PER_MS = 1000000; - private static final int NANOS_PER_SECOND = 1000000000; - - private final LayerView mView; - private TextLayer mFrameRateLayer; - private final ScrollbarLayer mHorizScrollLayer; - private final ScrollbarLayer mVertScrollLayer; - private final FadeRunnable mFadeRunnable; - private ByteBuffer mCoordByteBuffer; - private FloatBuffer mCoordBuffer; - private RenderContext mLastPageContext; - private int mMaxTextureSize; - private int mBackgroundColor; - private int mOverscrollColor; - - private long mLastFrameTime; - private final CopyOnWriteArrayList mTasks; - - private CopyOnWriteArrayList mExtraLayers = new CopyOnWriteArrayList(); - - // Dropped frames display - private int[] mFrameTimings; - private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames; - - // Render profiling output - private int mFramesRendered; - private float mCompleteFramesRendered; - private boolean mProfileRender; - private long mProfileOutputTime; - - private IntBuffer mPixelBuffer; - - // Used by GLES 2.0 - private int mProgram; - private int mPositionHandle; - private int mTextureHandle; - private int mSampleHandle; - private int mTMatrixHandle; - - // column-major matrix applied to each vertex to shift the viewport from - // one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by - // a factor of 2 to fill up the screen - public static final float[] DEFAULT_TEXTURE_MATRIX = { - 2.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 2.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 2.0f, 0.0f, - -1.0f, -1.0f, 0.0f, 1.0f - }; - - private static final int COORD_BUFFER_SIZE = 20; - - // The shaders run on the GPU directly, the vertex shader is only applying the - // matrix transform detailed above - - // Note we flip the y-coordinate in the vertex shader from a - // coordinate system with (0,0) in the top left to one with (0,0) in - // the bottom left. - - public static final String DEFAULT_VERTEX_SHADER = - "uniform mat4 uTMatrix;\n" + - "attribute vec4 vPosition;\n" + - "attribute vec2 aTexCoord;\n" + - "varying vec2 vTexCoord;\n" + - "void main() {\n" + - " gl_Position = uTMatrix * vPosition;\n" + - " vTexCoord.x = aTexCoord.x;\n" + - " vTexCoord.y = 1.0 - aTexCoord.y;\n" + - "}\n"; - - // We use highp because the screenshot textures - // we use are large and we stretch them a lot - // so we need all the precision we can get. - // Unfortunately, highp is not required by ES 2.0 - // so on GPU's like Mali we end up getting mediump - public static final String DEFAULT_FRAGMENT_SHADER = - "precision highp float;\n" + - "varying vec2 vTexCoord;\n" + - "uniform sampler2D sTexture;\n" + - "void main() {\n" + - " gl_FragColor = texture2D(sTexture, vTexCoord);\n" + - "}\n"; - - public LayerRenderer(LayerView view) { - mView = view; - mOverscrollColor = view.getContext().getResources().getColor(R.color.background_normal); - - Bitmap scrollbarImage = view.getScrollbarImage(); - IntSize size = new IntSize(scrollbarImage.getWidth(), scrollbarImage.getHeight()); - scrollbarImage = expandCanvasToPowerOfTwo(scrollbarImage, size); - - mTasks = new CopyOnWriteArrayList(); - mLastFrameTime = System.nanoTime(); - - mVertScrollLayer = new ScrollbarLayer(this, scrollbarImage, size, true); - mHorizScrollLayer = new ScrollbarLayer(this, diagonalFlip(scrollbarImage), new IntSize(size.height, size.width), false); - mFadeRunnable = new FadeRunnable(); - - mFrameTimings = new int[60]; - mCurrentFrame = mFrameTimingsSum = mDroppedFrames = 0; - - // Initialize the FloatBuffer that will be used to store all vertices and texture - // coordinates in draw() commands. - mCoordByteBuffer = DirectBufferAllocator.allocate(COORD_BUFFER_SIZE * 4); - mCoordByteBuffer.order(ByteOrder.nativeOrder()); - mCoordBuffer = mCoordByteBuffer.asFloatBuffer(); - - //Tabs.registerOnTabsChangedListener(this); - } - - private Bitmap expandCanvasToPowerOfTwo(Bitmap image, IntSize size) { - IntSize potSize = size.nextPowerOfTwo(); - if (size.equals(potSize)) { - return image; - } - // make the bitmap size a power-of-two in both dimensions if it's not already. - Bitmap potImage = Bitmap.createBitmap(potSize.width, potSize.height, image.getConfig()); - new Canvas(potImage).drawBitmap(image, new Matrix(), null); - return potImage; - } - - private Bitmap diagonalFlip(Bitmap image) { - Matrix rotation = new Matrix(); - rotation.setValues(new float[] { 0, 1, 0, 1, 0, 0, 0, 0, 1 }); // transform (x,y) into (y,x) - Bitmap rotated = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), rotation, true); - return rotated; - } - - public void destroy() { - DirectBufferAllocator.free(mCoordByteBuffer); - mCoordByteBuffer = null; - mCoordBuffer = null; - mHorizScrollLayer.destroy(); - mVertScrollLayer.destroy(); - if (mFrameRateLayer != null) { - mFrameRateLayer.destroy(); - } - //Tabs.unregisterOnTabsChangedListener(this); - } - - void onSurfaceCreated(EGLConfig config) { - checkMonitoringEnabled(); - createDefaultProgram(); - activateDefaultProgram(); - } - - public void createDefaultProgram() { - int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, DEFAULT_VERTEX_SHADER); - int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, DEFAULT_FRAGMENT_SHADER); - - mProgram = GLES20.glCreateProgram(); - GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program - GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program - GLES20.glLinkProgram(mProgram); // creates OpenGL program executables - - // Get handles to the vertex shader's vPosition, aTexCoord, sTexture, and uTMatrix members. - mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); - mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord"); - mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture"); - mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix"); - - int maxTextureSizeResult[] = new int[1]; - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0); - mMaxTextureSize = maxTextureSizeResult[0]; - } - - // Activates the shader program. - public void activateDefaultProgram() { - // Add the program to the OpenGL environment - GLES20.glUseProgram(mProgram); - - // Set the transformation matrix - GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false, DEFAULT_TEXTURE_MATRIX, 0); - - // Enable the arrays from which we get the vertex and texture coordinates - GLES20.glEnableVertexAttribArray(mPositionHandle); - GLES20.glEnableVertexAttribArray(mTextureHandle); - - GLES20.glUniform1i(mSampleHandle, 0); - - // TODO: Move these calls into a separate deactivate() call that is called after the - // underlay and overlay are rendered. - } - - // Deactivates the shader program. This must be done to avoid crashes after returning to the - // Gecko C++ compositor from Java. - public void deactivateDefaultProgram() { - GLES20.glDisableVertexAttribArray(mTextureHandle); - GLES20.glDisableVertexAttribArray(mPositionHandle); - GLES20.glUseProgram(0); - } - - public int getMaxTextureSize() { - return mMaxTextureSize; - } - - public void postRenderTask(RenderTask aTask) { - mTasks.add(aTask); - mView.requestRender(); - } - - public void removeRenderTask(RenderTask aTask) { - mTasks.remove(aTask); - } - - private void runRenderTasks(CopyOnWriteArrayList tasks, boolean after, long frameStartTime) { - for (RenderTask task : tasks) { - if (task.runAfter != after) { - continue; - } - - boolean stillRunning = task.run(frameStartTime - mLastFrameTime, frameStartTime); - - // Remove the task from the list if its finished - if (!stillRunning) { - tasks.remove(task); - } - } - } - - public void addLayer(Layer layer) { - synchronized (mExtraLayers) { - if (mExtraLayers.contains(layer)) { - mExtraLayers.remove(layer); - } - - mExtraLayers.add(layer); - } - } - - public void removeLayer(Layer layer) { - synchronized (mExtraLayers) { - mExtraLayers.remove(layer); - } - } - - private void printCheckerboardStats() { - Log.d(PROFTAG, "Frames rendered over last 1000ms: " + mCompleteFramesRendered + "/" + mFramesRendered); - mFramesRendered = 0; - mCompleteFramesRendered = 0; - } - - /** Used by robocop for testing purposes. Not for production use! */ - IntBuffer getPixels() { - IntBuffer pixelBuffer = IntBuffer.allocate(mView.getWidth() * mView.getHeight()); - synchronized (pixelBuffer) { - mPixelBuffer = pixelBuffer; - mView.requestRender(); - try { - pixelBuffer.wait(); - } catch (InterruptedException ie) { - } - mPixelBuffer = null; - } - return pixelBuffer; - } - - private RenderContext createScreenContext(ImmutableViewportMetrics metrics, PointF offset) { - RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight()); - RectF pageRect = metrics.getPageRect(); - - return createContext(viewport, pageRect, 1.0f, offset); - } - - private RenderContext createPageContext(ImmutableViewportMetrics metrics, PointF offset) { - RectF viewport = metrics.getViewport(); - RectF pageRect = metrics.getPageRect(); - float zoomFactor = metrics.zoomFactor; - - return createContext(new RectF(RectUtils.round(viewport)), pageRect, zoomFactor, offset); - } - - private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor, PointF offset) { - return new RenderContext(viewport, pageRect, zoomFactor, offset, mPositionHandle, mTextureHandle, - mCoordBuffer); - } - - private void updateDroppedFrames(long frameStartTime) { - int frameElapsedTime = (int)((System.nanoTime() - frameStartTime) / NANOS_PER_MS); - - /* Update the running statistics. */ - mFrameTimingsSum -= mFrameTimings[mCurrentFrame]; - mFrameTimingsSum += frameElapsedTime; - mDroppedFrames -= (mFrameTimings[mCurrentFrame] + 1) / MAX_FRAME_TIME; - mDroppedFrames += (frameElapsedTime + 1) / MAX_FRAME_TIME; - - mFrameTimings[mCurrentFrame] = frameElapsedTime; - mCurrentFrame = (mCurrentFrame + 1) % mFrameTimings.length; - - int averageTime = mFrameTimingsSum / mFrameTimings.length; - mFrameRateLayer.beginTransaction(); // called on compositor thread - try { - mFrameRateLayer.setText(averageTime + " ms/" + mDroppedFrames); - } finally { - mFrameRateLayer.endTransaction(); - } - } - - /* Given the new dimensions for the surface, moves the frame rate layer appropriately. */ - private void moveFrameRateLayer(int width, int height) { - mFrameRateLayer.beginTransaction(); // called on compositor thread - try { - Rect position = new Rect(width - FRAME_RATE_METER_WIDTH - 8, - height - FRAME_RATE_METER_HEIGHT + 8, - width - 8, - height + 8); - mFrameRateLayer.setPosition(position); - } finally { - mFrameRateLayer.endTransaction(); - } - } - - void checkMonitoringEnabled() { - /* Do this I/O off the main thread to minimize its impact on startup time. */ - new Thread(new Runnable() { - @Override - public void run() { - Context context = mView.getContext(); - SharedPreferences preferences = context.getSharedPreferences("GeckoApp", 0); - if (preferences.getBoolean("showFrameRate", false)) { - IntSize frameRateLayerSize = new IntSize(FRAME_RATE_METER_WIDTH, FRAME_RATE_METER_HEIGHT); - mFrameRateLayer = TextLayer.create(frameRateLayerSize, "-- ms/--"); - moveFrameRateLayer(mView.getWidth(), mView.getHeight()); - } - mProfileRender = Log.isLoggable(PROFTAG, Log.DEBUG); - } - }).start(); - } - - /* - * create a vertex shader type (GLES20.GL_VERTEX_SHADER) - * or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) - */ - public static int loadShader(int type, String shaderCode) { - int shader = GLES20.glCreateShader(type); - GLES20.glShaderSource(shader, shaderCode); - GLES20.glCompileShader(shader); - return shader; - } - - public Frame createFrame(ImmutableViewportMetrics metrics) { - return new Frame(metrics); - } - - class FadeRunnable implements Runnable { - private boolean mStarted; - private long mRunAt; - - void scheduleStartFade(long delay) { - mRunAt = SystemClock.elapsedRealtime() + delay; - if (!mStarted) { - mView.postDelayed(this, delay); - mStarted = true; - } - } - - void scheduleNextFadeFrame() { - if (mStarted) { - Log.e(LOGTAG, "scheduleNextFadeFrame() called while scheduled for starting fade"); - } - mView.postDelayed(this, 1000L / 60L); // request another frame at 60fps - } - - boolean timeToFade() { - return !mStarted; - } - - @Override - public void run() { - long timeDelta = mRunAt - SystemClock.elapsedRealtime(); - if (timeDelta > 0) { - // the run-at time was pushed back, so reschedule - mView.postDelayed(this, timeDelta); - } else { - // reached the run-at time, execute - mStarted = false; - mView.requestRender(); - } - } - } - - public class Frame { - // The timestamp recording the start of this frame. - private long mFrameStartTime; - // A fixed snapshot of the viewport metrics that this frame is using to render content. - private ImmutableViewportMetrics mFrameMetrics; - // A rendering context for page-positioned layers, and one for screen-positioned layers. - private RenderContext mPageContext, mScreenContext; - // Whether a layer was updated. - private boolean mUpdated; - private final Rect mPageRect; - private final Rect mAbsolutePageRect; - private final PointF mRenderOffset; - - public Frame(ImmutableViewportMetrics metrics) { - mFrameMetrics = metrics; - - // Work out the offset due to margins - Layer rootLayer = mView.getLayerClient().getRoot(); - mRenderOffset = mFrameMetrics.getMarginOffset(); - mPageContext = createPageContext(metrics, mRenderOffset); - mScreenContext = createScreenContext(metrics, mRenderOffset); - - RectF pageRect = mFrameMetrics.getPageRect(); - mAbsolutePageRect = RectUtils.round(pageRect); - - PointF origin = mFrameMetrics.getOrigin(); - pageRect.offset(-origin.x, -origin.y); - mPageRect = RectUtils.round(pageRect); - } - - private void setScissorRect() { - Rect scissorRect = transformToScissorRect(mPageRect); - GLES20.glEnable(GLES20.GL_SCISSOR_TEST); - GLES20.glScissor(scissorRect.left, scissorRect.top, - scissorRect.width(), scissorRect.height()); - } - - private Rect transformToScissorRect(Rect rect) { - IntSize screenSize = new IntSize(mFrameMetrics.getSize()); - - int left = Math.max(0, rect.left); - int top = Math.max(0, rect.top); - int right = Math.min(screenSize.width, rect.right); - int bottom = Math.min(screenSize.height, rect.bottom); - - Rect scissorRect = new Rect(left, screenSize.height - bottom, right, - (screenSize.height - bottom) + (bottom - top)); - scissorRect.offset(Math.round(-mRenderOffset.x), Math.round(-mRenderOffset.y)); - - return scissorRect; - } - - /** This function is invoked via JNI; be careful when modifying signature. */ - //@JNITarget - public void beginDrawing() { - mFrameStartTime = System.nanoTime(); - - TextureReaper.get().reap(); - TextureGenerator.get().fill(); - - mUpdated = true; - - Layer rootLayer = mView.getLayerClient().getRoot(); - - // Run through pre-render tasks - runRenderTasks(mTasks, false, mFrameStartTime); - - if (!mPageContext.fuzzyEquals(mLastPageContext) && !mView.isFullScreen()) { - // The viewport or page changed, so show the scrollbars again - // as per UX decision. Don't do this if we're in full-screen mode though. - mVertScrollLayer.unfade(); - mHorizScrollLayer.unfade(); - mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY); - } else if (mFadeRunnable.timeToFade()) { - boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade(); - if (stillFading) { - mFadeRunnable.scheduleNextFadeFrame(); - } - } - mLastPageContext = mPageContext; - - /* Update layers. */ - if (rootLayer != null) { - // Called on compositor thread. - mUpdated &= rootLayer.update(mPageContext); - } - - if (mFrameRateLayer != null) { - // Called on compositor thread. - mUpdated &= mFrameRateLayer.update(mScreenContext); - } - - mUpdated &= mVertScrollLayer.update(mPageContext); // called on compositor thread - mUpdated &= mHorizScrollLayer.update(mPageContext); // called on compositor thread - - for (Layer layer : mExtraLayers) { - mUpdated &= layer.update(mPageContext); // called on compositor thread - } - } - - /** Retrieves the bounds for the layer, rounded in such a way that it - * can be used as a mask for something that will render underneath it. - * This will round the bounds inwards, but stretch the mask towards any - * near page edge, where near is considered to be 'within 2 pixels'. - * Returns null if the given layer is null. - */ - private Rect getMaskForLayer(Layer layer) { - if (layer == null) { - return null; - } - - RectF bounds = RectUtils.contract(layer.getBounds(mPageContext), 1.0f, 1.0f); - Rect mask = RectUtils.roundIn(bounds); - - // If the mask is within two pixels of any page edge, stretch it over - // that edge. This is to avoid drawing thin slivers when masking - // layers. - if (mask.top <= 2) { - mask.top = -1; - } - if (mask.left <= 2) { - mask.left = -1; - } - - // Because we're drawing relative to the page-rect, we only need to - // take into account its width and height (and not its origin) - int pageRight = mPageRect.width(); - int pageBottom = mPageRect.height(); - - if (mask.right >= pageRight - 2) { - mask.right = pageRight + 1; - } - if (mask.bottom >= pageBottom - 2) { - mask.bottom = pageBottom + 1; - } - - return mask; - } - - private void clear(int color) { - GLES20.glClearColor(((color >> 16) & 0xFF) / 255.0f, - ((color >> 8) & 0xFF) / 255.0f, - (color & 0xFF) / 255.0f, - 0.0f); - // The bits set here need to match up with those used - // in gfx/layers/opengl/LayerManagerOGL.cpp. - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | - GLES20.GL_DEPTH_BUFFER_BIT); - } - - /** This function is invoked via JNI; be careful when modifying signature. */ - //@JNITarget - public void drawBackground() { - // Any GL state which is changed here must be restored in - // CompositorOGL::RestoreState - - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - - // Draw the overscroll background area as a solid color - clear(mOverscrollColor); - - // Update background color. - mBackgroundColor = mView.getBackgroundColor(); - - // Clear the page area to the page background colour. - setScissorRect(); - clear(mBackgroundColor); - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - } - - // Draws the layer the client added to us. - void drawRootLayer() { - Layer rootLayer = mView.getLayerClient().getRoot(); - if (rootLayer == null) { - return; - } - - rootLayer.draw(mPageContext); - } - - //@JNITarget - public void drawForeground() { - // Any GL state which is changed here must be restored in - // CompositorOGL::RestoreState - - /* Draw any extra layers that were added (likely plugins) */ - if (mExtraLayers.size() > 0) { - for (Layer layer : mExtraLayers) { - layer.draw(mPageContext); - } - } - - /* Draw the vertical scrollbar. */ - if (mPageRect.height() > mFrameMetrics.getHeight()) - mVertScrollLayer.draw(mPageContext); - - /* Draw the horizontal scrollbar. */ - if (mPageRect.width() > mFrameMetrics.getWidth()) - mHorizScrollLayer.draw(mPageContext); - - /* Measure how much of the screen is checkerboarding */ - Layer rootLayer = mView.getLayerClient().getRoot(); - if ((rootLayer != null) && - (mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) { - // Calculate the incompletely rendered area of the page - float checkerboard = 1.0f - /*GeckoAppShell*/LOKitShell.computeRenderIntegrity(); - - PanningPerfAPI.recordCheckerboard(checkerboard); - if (checkerboard < 0.0f || checkerboard > 1.0f) { - Log.e(LOGTAG, "Checkerboard value out of bounds: " + checkerboard); - } - - mCompleteFramesRendered += 1.0f - checkerboard; - mFramesRendered ++; - - if (mFrameStartTime - mProfileOutputTime > NANOS_PER_SECOND) { - mProfileOutputTime = mFrameStartTime; - printCheckerboardStats(); - } - } - - runRenderTasks(mTasks, true, mFrameStartTime); - - /* Draw the FPS. */ - if (mFrameRateLayer != null) { - updateDroppedFrames(mFrameStartTime); - - GLES20.glEnable(GLES20.GL_BLEND); - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); - mFrameRateLayer.draw(mScreenContext); - } - } - - /** This function is invoked via JNI; be careful when modifying signature. */ - //@JNITarget - public void endDrawing() { - // If a layer update requires further work, schedule another redraw - if (!mUpdated) - mView.requestRender(); - - PanningPerfAPI.recordFrameTime(); - - /* Used by robocop for testing purposes */ - IntBuffer pixelBuffer = mPixelBuffer; - if (mUpdated && pixelBuffer != null) { - synchronized (pixelBuffer) { - pixelBuffer.position(0); - GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(), - (int)mScreenContext.viewport.height(), GLES20.GL_RGBA, - GLES20.GL_UNSIGNED_BYTE, pixelBuffer); - pixelBuffer.notify(); - } - } - - // Remove background color once we've painted. GeckoLayerClient is - // responsible for setting this flag before current document is - // composited. - if (mView.getPaintState() == LayerView.PAINT_BEFORE_FIRST) { - mView.post(new Runnable() { - @Override - public void run() { - mView.getChildAt(0).setBackgroundColor(Color.TRANSPARENT); - } - }); - mView.setPaintState(LayerView.PAINT_AFTER_FIRST); - } - mLastFrameTime = mFrameStartTime; - } - } - - /*@Override - public void onTabChanged(final Tab tab, Tabs.TabEvents msg, Object data) { - // Sets the background of the newly selected tab. This background color - // gets cleared in endDrawing(). This function runs on the UI thread, - // but other code that touches the paint state is run on the compositor - // thread, so this may need to be changed if any problems appear. - if (msg == Tabs.TabEvents.SELECTED) { - if (mView != null) { - if (mView.getChildAt(0) != null) { - mView.getChildAt(0).setBackgroundColor(tab.getBackgroundColor()); - } - mView.setPaintState(LayerView.PAINT_START); - } - } - }*/ -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java deleted file mode 100644 index c489e7f044bc..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java +++ /dev/null @@ -1,692 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAccessibility; -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -//import org.mozilla.gecko.PrefsHelper; -//import org.mozilla.gecko.R; -//import org.mozilla.gecko.Tab; -//import org.mozilla.gecko.Tabs; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.TouchEventInterceptor; -import org.mozilla.gecko.ZoomConstraints; -//import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI; -//import org.mozilla.gecko.mozglue.RobocopTarget; -import org.mozilla.gecko.util.EventDispatcher; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.PixelFormat; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.SurfaceTexture; -import android.os.Build; -import android.os.Handler; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import android.view.TextureView; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.widget.FrameLayout; - -import java.nio.IntBuffer; -import java.util.ArrayList; - -/** - * A view rendered by the layer compositor. - * - * Note that LayerView is accessed by Robocop via reflection. - */ -public class LayerView extends FrameLayout /*implements Tabs.OnTabsChangedListener */ { - private static String LOGTAG = "GeckoLayerView"; - - private GeckoLayerClient mLayerClient; - private PanZoomController mPanZoomController; - private LayerMarginsAnimator mMarginsAnimator; - private GLController mGLController; - private InputConnectionHandler mInputConnectionHandler; - private LayerRenderer mRenderer; - /* Must be a PAINT_xxx constant */ - private int mPaintState; - private int mBackgroundColor; - private boolean mFullScreen; - - private SurfaceView mSurfaceView; - private TextureView mTextureView; - - private Listener mListener; - - /* This should only be modified on the Java UI thread. */ - private final ArrayList mTouchInterceptors; - private final Overscroll mOverscroll; - - /* Flags used to determine when to show the painted surface. */ - public static final int PAINT_START = 0; - public static final int PAINT_BEFORE_FIRST = 1; - public static final int PAINT_AFTER_FIRST = 2; - - public boolean shouldUseTextureView() { - // Disable TextureView support for now as it causes panning/zooming - // performance regressions (see bug 792259). Uncomment the code below - // once this bug is fixed. - return false; - - /* - // we can only use TextureView on ICS or higher - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - Log.i(LOGTAG, "Not using TextureView: not on ICS+"); - return false; - } - - try { - // and then we can only use it if we have a hardware accelerated window - Method m = View.class.getMethod("isHardwareAccelerated", (Class[]) null); - return (Boolean) m.invoke(this); - } catch (Exception e) { - Log.i(LOGTAG, "Not using TextureView: caught exception checking for hw accel: " + e.toString()); - return false; - } */ - } - - public LayerView(Context context, AttributeSet attrs) { - super(context, attrs); - - mGLController = GLController.getInstance(this); - mPaintState = PAINT_START; - mBackgroundColor = Color.WHITE; - - mTouchInterceptors = new ArrayList(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - mOverscroll = new OverscrollEdgeEffect(this); - } else { - mOverscroll = null; - } - //Tabs.registerOnTabsChangedListener(this); - } - - public LayerView(Context context) { - this(context, null); - } - - public void initializeView(EventDispatcher eventDispatcher) { - mLayerClient = new GeckoLayerClient(getContext(), this, eventDispatcher); - if (mOverscroll != null) { - mLayerClient.setOverscrollHandler(mOverscroll); - } - - mPanZoomController = mLayerClient.getPanZoomController(); - mMarginsAnimator = mLayerClient.getLayerMarginsAnimator(); - - mRenderer = new LayerRenderer(this); - mInputConnectionHandler = null; - - setFocusable(true); - setFocusableInTouchMode(true); - - //GeckoAccessibility.setDelegate(this); - } - - private Point getEventRadius(MotionEvent event) { - if (Build.VERSION.SDK_INT >= 9) { - return new Point((int)event.getToolMajor()/2, - (int)event.getToolMinor()/2); - } - - float size = event.getSize(); - DisplayMetrics displaymetrics = getContext().getResources().getDisplayMetrics(); - size = size * Math.min(displaymetrics.heightPixels, displaymetrics.widthPixels); - return new Point((int)size, (int)size); - } - - public void geckoConnected() { - // See if we want to force 16-bit colour before doing anything - /*PrefsHelper.getPref("gfx.android.rgb16.force", new PrefsHelper.PrefHandlerBase() { - @Override public void prefValue(String pref, boolean force16bit) { - if (force16bit) { - GeckoAppShell.setScreenDepthOverride(16); - } - } - });*/ - - mLayerClient.notifyGeckoReady(); - addTouchInterceptor(new TouchEventInterceptor() { - private PointF mInitialTouchPoint = null; - - @Override - public boolean onInterceptTouchEvent(View view, MotionEvent event) { - return false; - } - - @Override - public boolean onTouch(View view, MotionEvent event) { - if (event == null) { - return true; - } - - int action = event.getActionMasked(); - PointF point = new PointF(event.getX(), event.getY()); - if (action == MotionEvent.ACTION_DOWN) { - mInitialTouchPoint = point; - } - - if (mInitialTouchPoint != null && action == MotionEvent.ACTION_MOVE) { - Point p = getEventRadius(event); - - if (PointUtils.subtract(point, mInitialTouchPoint).length() < - Math.max(PanZoomController.CLICK_THRESHOLD, Math.min(Math.min(p.x, p.y), PanZoomController.PAN_THRESHOLD))) { - // Don't send the touchmove event if the users finger hasn't moved far. - // Necessary for Google Maps to work correctly. See bug 771099. - return true; - } else { - mInitialTouchPoint = null; - } - } - - //GeckoAppShell.sendEventToGecko(GeckoEvent.createMotionEvent(event, false)); - return true; - } - }); - } - - public void showSurface() { - // Fix this if TextureView support is turned back on above - mSurfaceView.setVisibility(View.VISIBLE); - } - - public void hideSurface() { - // Fix this if TextureView support is turned back on above - mSurfaceView.setVisibility(View.INVISIBLE); - } - - public void destroy() { - if (mLayerClient != null) { - mLayerClient.destroy(); - } - if (mRenderer != null) { - mRenderer.destroy(); - } - //Tabs.unregisterOnTabsChangedListener(this); - } - - public void addTouchInterceptor(final TouchEventInterceptor aTouchInterceptor) { - post(new Runnable() { - @Override - public void run() { - mTouchInterceptors.add(aTouchInterceptor); - } - }); - } - - public void removeTouchInterceptor(final TouchEventInterceptor aTouchInterceptor) { - post(new Runnable() { - @Override - public void run() { - mTouchInterceptors.remove(aTouchInterceptor); - } - }); - } - - private boolean runTouchInterceptors(MotionEvent event, boolean aOnTouch) { - boolean result = false; - for (TouchEventInterceptor i : mTouchInterceptors) { - if (aOnTouch) { - result |= i.onTouch(this, event); - } else { - result |= i.onInterceptTouchEvent(this, event); - } - } - - return result; - } - - @Override - public void dispatchDraw(final Canvas canvas) { - super.dispatchDraw(canvas); - - // We must have a layer client to get valid viewport metrics - if (mLayerClient != null && mOverscroll != null) { - mOverscroll.draw(canvas, getViewportMetrics()); - } - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { - requestFocus(); - } - - if (runTouchInterceptors(event, false)) { - return true; - } - if (mPanZoomController != null && mPanZoomController.onTouchEvent(event)) { - return true; - } - if (runTouchInterceptors(event, true)) { - return true; - } - return false; - } - - @Override - public boolean onHoverEvent(MotionEvent event) { - if (runTouchInterceptors(event, true)) { - return true; - } - return false; - } - - @Override - public boolean onGenericMotionEvent(MotionEvent event) { - if (mPanZoomController != null && mPanZoomController.onMotionEvent(event)) { - return true; - } - return false; - } - - @Override - protected void onAttachedToWindow() { - // This check should not be done before the view is attached to a window - // as hardware acceleration will not be enabled at that point. - // We must create and add the SurfaceView instance before the view tree - // is fully created to avoid flickering (see bug 801477). - if (shouldUseTextureView()) { - mTextureView = new TextureView(getContext()); - mTextureView.setSurfaceTextureListener(new SurfaceTextureListener()); - - // The background is set to this color when the LayerView is - // created, and it will be shown immediately at startup. Shortly - // after, the tab's background color will be used before any content - // is shown. - mTextureView.setBackgroundColor(Color.WHITE); - addView(mTextureView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - } else { - // This will stop PropertyAnimator from creating a drawing cache (i.e. a bitmap) - // from a SurfaceView, which is just not possible (the bitmap will be transparent). - setWillNotCacheDrawing(false); - - mSurfaceView = new LayerSurfaceView(getContext(), this); - mSurfaceView.setBackgroundColor(Color.WHITE); - addView(mSurfaceView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); - - SurfaceHolder holder = mSurfaceView.getHolder(); - holder.addCallback(new SurfaceListener()); - holder.setFormat(PixelFormat.RGB_565); - } - } - - //@RobocopTarget - public GeckoLayerClient getLayerClient() { return mLayerClient; } - public PanZoomController getPanZoomController() { return mPanZoomController; } - public LayerMarginsAnimator getLayerMarginsAnimator() { return mMarginsAnimator; } - - public ImmutableViewportMetrics getViewportMetrics() { - return mLayerClient.getViewportMetrics(); - } - - public void abortPanning() { - if (mPanZoomController != null) { - mPanZoomController.abortPanning(); - } - } - - public PointF convertViewPointToLayerPoint(PointF viewPoint) { - return mLayerClient.convertViewPointToLayerPoint(viewPoint); - } - - int getBackgroundColor() { - return mBackgroundColor; - } - - @Override - public void setBackgroundColor(int newColor) { - mBackgroundColor = newColor; - requestRender(); - } - - public void setZoomConstraints(ZoomConstraints constraints) { - mLayerClient.setZoomConstraints(constraints); - } - - public void setIsRTL(boolean aIsRTL) { - mLayerClient.setIsRTL(aIsRTL); - } - - public void setInputConnectionHandler(InputConnectionHandler inputConnectionHandler) { - mInputConnectionHandler = inputConnectionHandler; - mLayerClient.forceRedraw(null); - } - - @Override - public Handler getHandler() { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.getHandler(super.getHandler()); - return super.getHandler(); - } - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onCreateInputConnection(outAttrs); - return null; - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyPreIme(keyCode, event)) { - return true; - } - return false; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mPanZoomController != null && mPanZoomController.onKeyEvent(event)) { - return true; - } - if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyDown(keyCode, event)) { - return true; - } - return false; - } - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyLongPress(keyCode, event)) { - return true; - } - return false; - } - - @Override - public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { - if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event)) { - return true; - } - return false; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null && mInputConnectionHandler.onKeyUp(keyCode, event)) { - return true; - } - return false; - } - - public boolean isIMEEnabled() { - if (mInputConnectionHandler != null) { - return mInputConnectionHandler.isIMEEnabled(); - } - return false; - } - - public void requestRender() { - if (mListener != null) { - mListener.renderRequested(); - } - } - - public void addLayer(Layer layer) { - mRenderer.addLayer(layer); - } - - public void removeLayer(Layer layer) { - mRenderer.removeLayer(layer); - } - - public void postRenderTask(RenderTask task) { - mRenderer.postRenderTask(task); - } - - public void removeRenderTask(RenderTask task) { - mRenderer.removeRenderTask(task); - } - - public int getMaxTextureSize() { - return mRenderer.getMaxTextureSize(); - } - - /** Used by robocop for testing purposes. Not for production use! */ - //@RobocopTarget - public IntBuffer getPixels() { - return mRenderer.getPixels(); - } - - /* paintState must be a PAINT_xxx constant. */ - public void setPaintState(int paintState) { - mPaintState = paintState; - } - - public int getPaintState() { - return mPaintState; - } - - public LayerRenderer getRenderer() { - return mRenderer; - } - - public void setListener(Listener listener) { - mListener = listener; - } - - Listener getListener() { - return mListener; - } - - public GLController getGLController() { - return mGLController; - } - - private Bitmap getDrawable(String name) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inScaled = false; - Context context = getContext(); - int resId = context.getResources().getIdentifier(name, "drawable", context.getPackageName()); - return BitmapUtils.decodeResource(context, resId, options); - } - - Bitmap getScrollbarImage() { - return getDrawable("scrollbar"); - } - - /* When using a SurfaceView (mSurfaceView != null), resizing happens in two - * phases. First, the LayerView changes size, then, often some frames later, - * the SurfaceView changes size. Because of this, we need to split the - * resize into two phases to avoid jittering. - * - * The first phase is the LayerView size change. mListener is notified so - * that a synchronous draw can be performed (otherwise a blank frame will - * appear). - * - * The second phase is the SurfaceView size change. At this point, the - * backing GL surface is resized and another synchronous draw is performed. - * Gecko is also sent the new window size, and this will likely cause an - * extra draw a few frames later, after it's re-rendered and caught up. - * - * In the case that there is no valid GL surface (for example, when - * resuming, or when coming back from the awesomescreen), or we're using a - * TextureView instead of a SurfaceView, the first phase is skipped. - */ - private void onSizeChanged(int width, int height) { - if (!mGLController.isCompositorCreated()) { - return; - } - - surfaceChanged(width, height); - - if (mSurfaceView == null) { - return; - } - - if (mListener != null) { - mListener.sizeChanged(width, height); - } - - if (mOverscroll != null) { - mOverscroll.setSize(width, height); - } - } - - private void surfaceChanged(int width, int height) { - mGLController.serverSurfaceChanged(width, height); - - if (mListener != null) { - mListener.surfaceChanged(width, height); - } - - if (mOverscroll != null) { - mOverscroll.setSize(width, height); - } - } - - private void onDestroyed() { - mGLController.serverSurfaceDestroyed(); - } - - public Object getNativeWindow() { - if (mSurfaceView != null) - return mSurfaceView.getHolder(); - - return mTextureView.getSurfaceTexture(); - } - - //@WrapElementForJNI(allowMultithread = true, stubName = "RegisterCompositorWrapper") - public static GLController registerCxxCompositor() { - try { - LayerView layerView = /*GeckoAppShell*/LOKitShell.getLayerView(); - GLController controller = layerView.getGLController(); - controller.compositorCreated(); - return controller; - } catch (Exception e) { - Log.e(LOGTAG, "Error registering compositor!", e); - return null; - } - } - - public interface Listener { - void renderRequested(); - void sizeChanged(int width, int height); - void surfaceChanged(int width, int height); - } - - private class SurfaceListener implements SurfaceHolder.Callback { - @Override - public void surfaceChanged(SurfaceHolder holder, int format, int width, - int height) { - onSizeChanged(width, height); - } - - @Override - public void surfaceCreated(SurfaceHolder holder) { - } - - @Override - public void surfaceDestroyed(SurfaceHolder holder) { - onDestroyed(); - } - } - - /* A subclass of SurfaceView to listen to layout changes, as - * View.OnLayoutChangeListener requires API level 11. - */ - private class LayerSurfaceView extends SurfaceView { - LayerView mParent; - - public LayerSurfaceView(Context aContext, LayerView aParent) { - super(aContext); - mParent = aParent; - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (changed) { - mParent.surfaceChanged(right - left, bottom - top); - } - } - } - - private class SurfaceTextureListener implements TextureView.SurfaceTextureListener { - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - // We don't do this for surfaceCreated above because it is always followed by a surfaceChanged, - // but that is not the case here. - onSizeChanged(width, height); - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - onDestroyed(); - return true; // allow Android to call release() on the SurfaceTexture, we are done drawing to it - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - onSizeChanged(width, height); - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - - } - } - - @Override - public void setOverScrollMode(int overscrollMode) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - super.setOverScrollMode(overscrollMode); - } - if (mPanZoomController != null) { - mPanZoomController.setOverScrollMode(overscrollMode); - } - } - - @Override - public int getOverScrollMode() { - if (mPanZoomController != null) { - return mPanZoomController.getOverScrollMode(); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { - return super.getOverScrollMode(); - } - return View.OVER_SCROLL_ALWAYS; - } - - @Override - public void onFocusChanged (boolean gainFocus, int direction, Rect previouslyFocusedRect) { - super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); - //GeckoAccessibility.onLayerViewFocusChanged(this, gainFocus); - } - - public void setFullScreen(boolean fullScreen) { - mFullScreen = fullScreen; - } - - public boolean isFullScreen() { - return mFullScreen; - } - - /*@Override - public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) { - if (msg == Tabs.TabEvents.VIEWPORT_CHANGE && Tabs.getInstance().isSelectedTab(tab) && mLayerClient != null) { - setZoomConstraints(tab.getZoomConstraints()); - setIsRTL(tab.getIsRTL()); - } - }*/ -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java deleted file mode 100644 index e442444d5a7b..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/Overscroll.java +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Canvas; - -public interface Overscroll { - // The axis to show overscroll on. - public enum Axis { - X, - Y, - }; - - public void draw(final Canvas canvas, final ImmutableViewportMetrics metrics); - public void setSize(final int width, final int height); - public void setVelocity(final float velocity, final Axis axis); - public void setDistance(final float distance, final Axis axis); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java deleted file mode 100644 index 9ab64d5f3e51..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/OverscrollEdgeEffect.java +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.content.Context; -import android.graphics.Canvas; -import android.os.Build; -import android.widget.EdgeEffect; -import android.view.View; - - -public class OverscrollEdgeEffect implements Overscroll { - // Used to index particular edges in the edges array - private static final int TOP = 0; - private static final int BOTTOM = 1; - private static final int LEFT = 2; - private static final int RIGHT = 3; - - // All four edges of the screen - private final EdgeEffect[] mEdges = new EdgeEffect[4]; - - // The view we're showing this overscroll on. - private final View mView; - - public OverscrollEdgeEffect(final View v) { - mView = v; - Context context = v.getContext(); - for (int i = 0; i < 4; i++) { - mEdges[i] = new EdgeEffect(context); - } - } - - public void setSize(final int width, final int height) { - mEdges[LEFT].setSize(height, width); - mEdges[RIGHT].setSize(height, width); - mEdges[TOP].setSize(width, height); - mEdges[BOTTOM].setSize(width, height); - } - - private EdgeEffect getEdgeForAxisAndSide(final Axis axis, final float side) { - if (axis == Axis.Y) { - if (side < 0) { - return mEdges[TOP]; - } else { - return mEdges[BOTTOM]; - } - } else { - if (side < 0) { - return mEdges[LEFT]; - } else { - return mEdges[RIGHT]; - } - } - } - - private void invalidate() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - mView.postInvalidateOnAnimation(); - } else { - mView.postInvalidateDelayed(10); - } - } - - public void setVelocity(final float velocity, final Axis axis) { - final EdgeEffect edge = getEdgeForAxisAndSide(axis, velocity); - - // If we're showing overscroll already, start fading it out. - if (!edge.isFinished()) { - edge.onRelease(); - } else { - // Otherwise, show an absorb effect - edge.onAbsorb((int)velocity); - } - - invalidate(); - } - - public void setDistance(final float distance, final Axis axis) { - // The first overscroll event often has zero distance. Throw it out - if (distance == 0.0f) { - return; - } - - final EdgeEffect edge = getEdgeForAxisAndSide(axis, (int)distance); - edge.onPull(distance / (axis == Axis.X ? mView.getWidth() : mView.getHeight())); - invalidate(); - } - - public void draw(final Canvas canvas, final ImmutableViewportMetrics metrics) { - if (metrics == null) { - return; - } - - // If we're pulling an edge, or fading it out, draw! - boolean invalidate = false; - if (!mEdges[TOP].isFinished()) { - invalidate |= draw(mEdges[TOP], canvas, metrics.marginLeft, metrics.marginTop, 0); - } - - if (!mEdges[BOTTOM].isFinished()) { - invalidate |= draw(mEdges[BOTTOM], canvas, mView.getWidth(), mView.getHeight(), 180); - } - - if (!mEdges[LEFT].isFinished()) { - invalidate |= draw(mEdges[LEFT], canvas, metrics.marginLeft, mView.getHeight(), 270); - } - - if (!mEdges[RIGHT].isFinished()) { - invalidate |= draw(mEdges[RIGHT], canvas, mView.getWidth(), metrics.marginTop, 90); - } - - // If the edge effect is animating off screen, invalidate. - if (invalidate) { - invalidate(); - } - } - - public boolean draw(final EdgeEffect edge, final Canvas canvas, final float translateX, final float translateY, final float rotation) { - final int state = canvas.save(); - canvas.translate(translateX, translateY); - canvas.rotate(rotation); - boolean invalidate = edge.draw(canvas); - canvas.restoreToCount(state); - - return invalidate; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java deleted file mode 100644 index 5ef25a64628c..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomController.java +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.util.EventDispatcher; - -import android.graphics.PointF; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.View; - -public interface PanZoomController { - // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans - // between the touch-down and touch-up of a click). In units of density-independent pixels. - public static final float PAN_THRESHOLD = 1/16f * /*GeckoAppShell*/LOKitShell.getDpi(); - - // Threshold for sending touch move events to content - public static final float CLICK_THRESHOLD = 1/50f * /*GeckoAppShell*/LOKitShell.getDpi(); - - static class Factory { - static PanZoomController create(PanZoomTarget target, View view, EventDispatcher dispatcher) { - return new JavaPanZoomController(target, view, dispatcher); - } - } - - public void destroy(); - - public boolean onTouchEvent(MotionEvent event); - public boolean onMotionEvent(MotionEvent event); - public boolean onKeyEvent(KeyEvent event); - public void notifyDefaultActionPrevented(boolean prevented); - - public boolean getRedrawHint(); - public PointF getVelocityVector(); - - public void pageRectUpdated(); - public void abortPanning(); - public void abortAnimation(); - - public void setOverScrollMode(int overscrollMode); - public int getOverScrollMode(); - - public void setOverscrollHandler(final Overscroll controller); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java deleted file mode 100644 index c32f213937f2..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanZoomTarget.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.ZoomConstraints; - -import android.graphics.PointF; -import android.graphics.RectF; - -public interface PanZoomTarget { - public ImmutableViewportMetrics getViewportMetrics(); - public ZoomConstraints getZoomConstraints(); - public boolean isFullScreen(); - public RectF getMaxMargins(); - - public void setAnimationTarget(ImmutableViewportMetrics viewport); - public void setViewportMetrics(ImmutableViewportMetrics viewport); - public void scrollBy(float dx, float dy); - public void scrollMarginsBy(float dx, float dy); - public void panZoomStopped(); - /** This triggers an (asynchronous) viewport update/redraw. */ - public void forceRedraw(DisplayPortMetrics displayPort); - - public boolean post(Runnable action); - public boolean postDelayed(Runnable action, long delayMillis); - public void postRenderTask(RenderTask task); - public void removeRenderTask(RenderTask task); - public Object getLock(); - public PointF convertViewPointToLayerPoint(PointF viewPoint); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java deleted file mode 100644 index 7c2ca2b9d030..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java +++ /dev/null @@ -1,123 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.mozglue.RobocopTarget; - -import android.os.SystemClock; -import android.util.Log; - -import java.util.ArrayList; -import java.util.List; - -public class PanningPerfAPI { - private static final String LOGTAG = "GeckoPanningPerfAPI"; - - // make this large enough to avoid having to resize the frame time - // list, as that may be expensive and impact the thing we're trying - // to measure. - private static final int EXPECTED_FRAME_COUNT = 2048; - - private static boolean mRecordingFrames = false; - private static List mFrameTimes; - private static long mFrameStartTime; - - private static boolean mRecordingCheckerboard = false; - private static List mCheckerboardAmounts; - private static long mCheckerboardStartTime; - - private static void initialiseRecordingArrays() { - if (mFrameTimes == null) { - mFrameTimes = new ArrayList(EXPECTED_FRAME_COUNT); - } else { - mFrameTimes.clear(); - } - if (mCheckerboardAmounts == null) { - mCheckerboardAmounts = new ArrayList(EXPECTED_FRAME_COUNT); - } else { - mCheckerboardAmounts.clear(); - } - } - - //@RobocopTarget - public static void startFrameTimeRecording() { - if (mRecordingFrames || mRecordingCheckerboard) { - Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!"); - return; - } - mRecordingFrames = true; - initialiseRecordingArrays(); - mFrameStartTime = SystemClock.uptimeMillis(); - } - - //@RobocopTarget - public static List stopFrameTimeRecording() { - if (!mRecordingFrames) { - Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!"); - return null; - } - mRecordingFrames = false; - return mFrameTimes; - } - - public static void recordFrameTime() { - // this will be called often, so try to make it as quick as possible - if (mRecordingFrames) { - mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime); - } - } - - public static boolean isRecordingCheckerboard() { - return mRecordingCheckerboard; - } - - //@RobocopTarget - public static void startCheckerboardRecording() { - if (mRecordingCheckerboard || mRecordingFrames) { - Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!"); - return; - } - mRecordingCheckerboard = true; - initialiseRecordingArrays(); - mCheckerboardStartTime = SystemClock.uptimeMillis(); - } - - //@RobocopTarget - public static List stopCheckerboardRecording() { - if (!mRecordingCheckerboard) { - Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!"); - return null; - } - mRecordingCheckerboard = false; - - // We take the number of values in mCheckerboardAmounts here, as there's - // the possibility that this function is called while recordCheckerboard - // is still executing. As values are added to this list last, we use - // this number as the canonical number of recordings. - int values = mCheckerboardAmounts.size(); - - // The score will be the sum of all the values in mCheckerboardAmounts, - // so weight the checkerboard values by time so that frame-rate and - // run-length don't affect score. - long lastTime = 0; - float totalTime = mFrameTimes.get(values - 1); - for (int i = 0; i < values; i++) { - long elapsedTime = mFrameTimes.get(i) - lastTime; - mCheckerboardAmounts.set(i, mCheckerboardAmounts.get(i) * elapsedTime / totalTime); - lastTime += elapsedTime; - } - - return mCheckerboardAmounts; - } - - public static void recordCheckerboard(float amount) { - // this will be called often, so try to make it as quick as possible - if (mRecordingCheckerboard) { - mFrameTimes.add(SystemClock.uptimeMillis() - mCheckerboardStartTime); - mCheckerboardAmounts.add(amount); - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java deleted file mode 100644 index 8db329c9fe8d..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.graphics.Point; -import android.graphics.PointF; - -public final class PointUtils { - public static PointF add(PointF one, PointF two) { - return new PointF(one.x + two.x, one.y + two.y); - } - - public static PointF subtract(PointF one, PointF two) { - return new PointF(one.x - two.x, one.y - two.y); - } - - public static PointF scale(PointF point, float factor) { - return new PointF(point.x * factor, point.y * factor); - } - - public static Point round(PointF point) { - return new Point(Math.round(point.x), Math.round(point.y)); - } - - /* Computes the magnitude of the given vector. */ - public static float distance(PointF point) { - return (float)Math.sqrt(point.x * point.x + point.y * point.y); - } - - /** Computes the scalar distance between two points. */ - public static float distance(PointF one, PointF two) { - return PointF.length(one.x - two.x, one.y - two.y); - } - - public static JSONObject toJSON(PointF point) throws JSONException { - // Ensure we put ints, not longs, because Gecko message handlers call getInt(). - int x = Math.round(point.x); - int y = Math.round(point.y); - JSONObject json = new JSONObject(); - json.put("x", x); - json.put("y", y); - return json; - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java deleted file mode 100644 index b7c381c688b0..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ProgressiveUpdateData.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - -/** - * This is the data structure that's returned by the progressive tile update - * callback function. It encompasses the current viewport and a boolean value - * representing whether the front-end is interested in the current progressive - * update continuing. - */ -//@WrapEntireClassForJNI -public class ProgressiveUpdateData { - public float x; - public float y; - public float width; - public float height; - public float scale; - public boolean abort; - - public void setViewport(ImmutableViewportMetrics viewport) { - this.x = viewport.viewportRectLeft; - this.y = viewport.viewportRectTop; - this.width = viewport.viewportRectRight - this.x; - this.height = viewport.viewportRectBottom - this.y; - this.scale = viewport.zoomFactor; - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java deleted file mode 100644 index 22151db76921..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java +++ /dev/null @@ -1,126 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.FloatUtils; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; - -public final class RectUtils { - private RectUtils() {} - - public static Rect create(JSONObject json) { - try { - int x = json.getInt("x"); - int y = json.getInt("y"); - int width = json.getInt("width"); - int height = json.getInt("height"); - return new Rect(x, y, x + width, y + height); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - public static String toJSON(RectF rect) { - StringBuilder sb = new StringBuilder(256); - sb.append("{ \"left\": ").append(rect.left) - .append(", \"top\": ").append(rect.top) - .append(", \"right\": ").append(rect.right) - .append(", \"bottom\": ").append(rect.bottom) - .append('}'); - return sb.toString(); - } - - public static RectF expand(RectF rect, float moreWidth, float moreHeight) { - float halfMoreWidth = moreWidth / 2; - float halfMoreHeight = moreHeight / 2; - return new RectF(rect.left - halfMoreWidth, - rect.top - halfMoreHeight, - rect.right + halfMoreWidth, - rect.bottom + halfMoreHeight); - } - - public static RectF contract(RectF rect, float lessWidth, float lessHeight) { - float halfLessWidth = lessWidth / 2.0f; - float halfLessHeight = lessHeight / 2.0f; - return new RectF(rect.left + halfLessWidth, - rect.top + halfLessHeight, - rect.right - halfLessWidth, - rect.bottom - halfLessHeight); - } - - public static RectF intersect(RectF one, RectF two) { - float left = Math.max(one.left, two.left); - float top = Math.max(one.top, two.top); - float right = Math.min(one.right, two.right); - float bottom = Math.min(one.bottom, two.bottom); - return new RectF(left, top, Math.max(right, left), Math.max(bottom, top)); - } - - public static RectF scale(RectF rect, float scale) { - float x = rect.left * scale; - float y = rect.top * scale; - return new RectF(x, y, - x + (rect.width() * scale), - y + (rect.height() * scale)); - } - - public static RectF scaleAndRound(RectF rect, float scale) { - float left = rect.left * scale; - float top = rect.top * scale; - return new RectF(Math.round(left), - Math.round(top), - Math.round(left + (rect.width() * scale)), - Math.round(top + (rect.height() * scale))); - } - - /** Returns the nearest integer rect of the given rect. */ - public static Rect round(RectF rect) { - Rect r = new Rect(); - round(rect, r); - return r; - } - - public static void round(RectF rect, Rect dest) { - dest.set(Math.round(rect.left), Math.round(rect.top), - Math.round(rect.right), Math.round(rect.bottom)); - } - - public static Rect roundIn(RectF rect) { - return new Rect((int)Math.ceil(rect.left), (int)Math.ceil(rect.top), - (int)Math.floor(rect.right), (int)Math.floor(rect.bottom)); - } - - public static IntSize getSize(Rect rect) { - return new IntSize(rect.width(), rect.height()); - } - - public static Point getOrigin(Rect rect) { - return new Point(rect.left, rect.top); - } - - public static PointF getOrigin(RectF rect) { - return new PointF(rect.left, rect.top); - } - - public static boolean fuzzyEquals(RectF a, RectF b) { - if (a == null && b == null) - return true; - else if ((a == null && b != null) || (a != null && b == null)) - return false; - else - return FloatUtils.fuzzyEquals(a.top, b.top) - && FloatUtils.fuzzyEquals(a.left, b.left) - && FloatUtils.fuzzyEquals(a.right, b.right) - && FloatUtils.fuzzyEquals(a.bottom, b.bottom); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java deleted file mode 100644 index 39c6eacb59f8..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/RenderTask.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -/** - * A class used to schedule a callback to occur when the next frame is drawn. - * Subclasses must redefine the internalRun method, not the run method. - */ -public abstract class RenderTask { - /** - * Whether to run the task after the render, or before. - */ - public final boolean runAfter; - - /** - * Time when this task has first run, in ns. Useful for tasks which run for a specific duration. - */ - private long mStartTime; - - /** - * Whether we should initialise mStartTime on the next frame run. - */ - private boolean mResetStartTime = true; - - /** - * The callback to run on each frame. timeDelta is the time elapsed since - * the last call, in nanoseconds. Returns true if it should continue - * running, or false if it should be removed from the task queue. Returning - * true implicitly schedules a redraw. - * - * This method first initializes the start time if resetStartTime has been invoked, - * then calls internalRun. - * - * Note : subclasses should override internalRun. - * - * @param timeDelta the time between the beginning of last frame and the beginning of this frame, in ns. - * @param currentFrameStartTime the startTime of the current frame, in ns. - * @return true if animation should be run at the next frame, false otherwise - * @see org.mozilla.gecko.gfx.RenderTask#internalRun(long, long) - */ - public final boolean run(long timeDelta, long currentFrameStartTime) { - if (mResetStartTime) { - mStartTime = currentFrameStartTime; - mResetStartTime = false; - } - return internalRun(timeDelta, currentFrameStartTime); - } - - /** - * Abstract method to be overridden by subclasses. - * @param timeDelta the time between the beginning of last frame and the beginning of this frame, in ns - * @param currentFrameStartTime the startTime of the current frame, in ns. - * @return true if animation should be run at the next frame, false otherwise - */ - protected abstract boolean internalRun(long timeDelta, long currentFrameStartTime); - - public RenderTask(boolean aRunAfter) { - runAfter = aRunAfter; - } - - /** - * Get the start time of this task. - * It is the start time of the first frame this task was run on. - * @return the start time in ns - */ - public long getStartTime() { - return mStartTime; - } - - /** - * Schedule a reset of the recorded start time next time {@link org.mozilla.gecko.gfx.RenderTask#run(long, long)} is run. - * @see org.mozilla.gecko.gfx.RenderTask#getStartTime() - */ - public void resetStartTime() { - mResetStartTime = true; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java deleted file mode 100644 index 043c82775467..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java +++ /dev/null @@ -1,297 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.FloatUtils; - -import android.graphics.Bitmap; -import android.graphics.Rect; -import android.graphics.RectF; -import android.opengl.GLES20; - -import java.nio.FloatBuffer; - -public class ScrollbarLayer extends TileLayer { - public static final long FADE_DELAY = 500; // milliseconds before fade-out starts - private static final float FADE_AMOUNT = 0.03f; // how much (as a percent) the scrollbar should fade per frame - - private final boolean mVertical; - private float mOpacity; - - // To avoid excessive GC, declare some objects here that would otherwise - // be created and destroyed frequently during draw(). - private final RectF mBarRectF; - private final Rect mBarRect; - private final float[] mCoords; - private final RectF mCapRectF; - - private LayerRenderer mRenderer; - private int mProgram; - private int mPositionHandle; - private int mTextureHandle; - private int mSampleHandle; - private int mTMatrixHandle; - private int mOpacityHandle; - - // Fragment shader used to draw the scroll-bar with opacity - private static final String FRAGMENT_SHADER = - "precision mediump float;\n" + - "varying vec2 vTexCoord;\n" + - "uniform sampler2D sTexture;\n" + - "uniform float uOpacity;\n" + - "void main() {\n" + - " gl_FragColor = texture2D(sTexture, vTexCoord);\n" + - " gl_FragColor.a *= uOpacity;\n" + - "}\n"; - - // Dimensions of the texture bitmap (will always be power-of-two) - private final int mTexWidth; - private final int mTexHeight; - // Some useful dimensions of the actual content in the bitmap - private final int mBarWidth; - private final int mCapLength; - - private final Rect mStartCapTexCoords; // top/left endcap coordinates - private final Rect mBodyTexCoords; // 1-pixel slice of the texture to be stretched - private final Rect mEndCapTexCoords; // bottom/right endcap coordinates - - ScrollbarLayer(LayerRenderer renderer, Bitmap scrollbarImage, IntSize imageSize, boolean vertical) { - super(new BufferedCairoImage(scrollbarImage), TileLayer.PaintMode.NORMAL); - mRenderer = renderer; - mVertical = vertical; - - mBarRectF = new RectF(); - mBarRect = new Rect(); - mCoords = new float[20]; - mCapRectF = new RectF(); - - mTexHeight = scrollbarImage.getHeight(); - mTexWidth = scrollbarImage.getWidth(); - - if (mVertical) { - mBarWidth = imageSize.width; - mCapLength = imageSize.height / 2; - mStartCapTexCoords = new Rect(0, mTexHeight - mCapLength, imageSize.width, mTexHeight); - mBodyTexCoords = new Rect(0, mTexHeight - (mCapLength + 1), imageSize.width, mTexHeight - mCapLength); - mEndCapTexCoords = new Rect(0, mTexHeight - imageSize.height, imageSize.width, mTexHeight - (mCapLength + 1)); - } else { - mBarWidth = imageSize.height; - mCapLength = imageSize.width / 2; - mStartCapTexCoords = new Rect(0, mTexHeight - imageSize.height, mCapLength, mTexHeight); - mBodyTexCoords = new Rect(mCapLength, mTexHeight - imageSize.height, mCapLength + 1, mTexHeight); - mEndCapTexCoords = new Rect(mCapLength + 1, mTexHeight - imageSize.height, imageSize.width, mTexHeight); - } - } - - private void createProgram() { - int vertexShader = LayerRenderer.loadShader(GLES20.GL_VERTEX_SHADER, - LayerRenderer.DEFAULT_VERTEX_SHADER); - int fragmentShader = LayerRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, - FRAGMENT_SHADER); - - mProgram = GLES20.glCreateProgram(); - GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program - GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program - GLES20.glLinkProgram(mProgram); // creates OpenGL program executables - - // Get handles to the shaders' vPosition, aTexCoord, sTexture, and uTMatrix members. - mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); - mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord"); - mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture"); - mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix"); - mOpacityHandle = GLES20.glGetUniformLocation(mProgram, "uOpacity"); - } - - private void activateProgram() { - // Add the program to the OpenGL environment - GLES20.glUseProgram(mProgram); - - // Set the transformation matrix - GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false, - LayerRenderer.DEFAULT_TEXTURE_MATRIX, 0); - - // Enable the arrays from which we get the vertex and texture coordinates - GLES20.glEnableVertexAttribArray(mPositionHandle); - GLES20.glEnableVertexAttribArray(mTextureHandle); - - GLES20.glUniform1i(mSampleHandle, 0); - GLES20.glUniform1f(mOpacityHandle, mOpacity); - } - - private void deactivateProgram() { - GLES20.glDisableVertexAttribArray(mTextureHandle); - GLES20.glDisableVertexAttribArray(mPositionHandle); - GLES20.glUseProgram(0); - } - - /** - * Decrease the opacity of the scrollbar by one frame's worth. - * Return true if the opacity was decreased, or false if the scrollbars - * are already fully faded out. - */ - public boolean fade() { - if (FloatUtils.fuzzyEquals(mOpacity, 0.0f)) { - return false; - } - beginTransaction(); // called on compositor thread - mOpacity = Math.max(mOpacity - FADE_AMOUNT, 0.0f); - endTransaction(); - return true; - } - - /** - * Restore the opacity of the scrollbar to fully opaque. - * Return true if the opacity was changed, or false if the scrollbars - * are already fully opaque. - */ - public boolean unfade() { - if (FloatUtils.fuzzyEquals(mOpacity, 1.0f)) { - return false; - } - beginTransaction(); // called on compositor thread - mOpacity = 1.0f; - endTransaction(); - return true; - } - - @Override - public void draw(RenderContext context) { - if (!initialized()) - return; - - // Create the shader program, if necessary - if (mProgram == 0) { - createProgram(); - } - - // Enable the shader program - mRenderer.deactivateDefaultProgram(); - activateProgram(); - - GLES20.glEnable(GLES20.GL_BLEND); - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); - - if (mVertical) { - getVerticalRect(context, mBarRectF); - } else { - getHorizontalRect(context, mBarRectF); - } - RectUtils.round(mBarRectF, mBarRect); - - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID()); - - float viewWidth = context.viewport.width(); - float viewHeight = context.viewport.height(); - - mBarRectF.set(mBarRect.left, viewHeight - mBarRect.top, mBarRect.right, viewHeight - mBarRect.bottom); - mBarRectF.offset(context.offset.x, -context.offset.y); - - // We take a 1-pixel slice from the center of the image and scale it to become the bar - fillRectCoordBuffer(mCoords, mBarRectF, viewWidth, viewHeight, mBodyTexCoords, mTexWidth, mTexHeight); - - // Get the buffer and handles from the context - FloatBuffer coordBuffer = context.coordBuffer; - int positionHandle = mPositionHandle; - int textureHandle = mTextureHandle; - - // Make sure we are at position zero in the buffer in case other draw methods did not - // clean up after themselves - coordBuffer.position(0); - coordBuffer.put(mCoords); - - // Unbind any the current array buffer so we can use client side buffers - GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture coordinates. - coordBuffer.position(0); - if (mVertical) { - // top endcap - mCapRectF.set(mBarRectF.left, mBarRectF.top + mCapLength, mBarRectF.right, mBarRectF.top); - } else { - // left endcap - mCapRectF.set(mBarRectF.left - mCapLength, mBarRectF.bottom + mBarWidth, mBarRectF.left, mBarRectF.bottom); - } - - fillRectCoordBuffer(mCoords, mCapRectF, viewWidth, viewHeight, mStartCapTexCoords, mTexWidth, mTexHeight); - coordBuffer.put(mCoords); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture coordinates. - coordBuffer.position(0); - if (mVertical) { - // bottom endcap - mCapRectF.set(mBarRectF.left, mBarRectF.bottom, mBarRectF.right, mBarRectF.bottom - mCapLength); - } else { - // right endcap - mCapRectF.set(mBarRectF.right, mBarRectF.bottom + mBarWidth, mBarRectF.right + mCapLength, mBarRectF.bottom); - } - fillRectCoordBuffer(mCoords, mCapRectF, viewWidth, viewHeight, mEndCapTexCoords, mTexWidth, mTexHeight); - coordBuffer.put(mCoords); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture coordinates. - coordBuffer.position(0); - - // Enable the default shader program again - deactivateProgram(); - mRenderer.activateDefaultProgram(); - } - - private void getVerticalRect(RenderContext context, RectF dest) { - RectF viewport = context.viewport; - RectF pageRect = context.pageRect; - float viewportHeight = viewport.height() - context.offset.y; - float barStart = ((viewport.top - context.offset.y - pageRect.top) * (viewportHeight / pageRect.height())) + mCapLength; - float barEnd = ((viewport.bottom - context.offset.y - pageRect.top) * (viewportHeight / pageRect.height())) - mCapLength; - if (barStart > barEnd) { - float middle = (barStart + barEnd) / 2.0f; - barStart = barEnd = middle; - } - dest.set(viewport.width() - mBarWidth, barStart, viewport.width(), barEnd); - } - - private void getHorizontalRect(RenderContext context, RectF dest) { - RectF viewport = context.viewport; - RectF pageRect = context.pageRect; - float viewportWidth = viewport.width() - context.offset.x; - float barStart = ((viewport.left - context.offset.x - pageRect.left) * (viewport.width() / pageRect.width())) + mCapLength; - float barEnd = ((viewport.right - context.offset.x - pageRect.left) * (viewport.width() / pageRect.width())) - mCapLength; - if (barStart > barEnd) { - float middle = (barStart + barEnd) / 2.0f; - barStart = barEnd = middle; - } - dest.set(barStart, viewport.height() - mBarWidth, barEnd, viewport.height()); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java deleted file mode 100644 index b3f6fcbc55e9..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SimpleScaleGestureDetector.java +++ /dev/null @@ -1,322 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.json.JSONException; - -import android.graphics.PointF; -import android.util.Log; -import android.view.MotionEvent; - -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Stack; - -/** - * A less buggy, and smoother, replacement for the built-in Android ScaleGestureDetector. - * - * This gesture detector is more reliable than the built-in ScaleGestureDetector because: - * - * - It doesn't assume that pointer IDs are numbered 0 and 1. - * - * - It doesn't attempt to correct for "slop" when resting one's hand on the device. On some - * devices (e.g. the Droid X) this can cause the ScaleGestureDetector to lose track of how many - * pointers are down, with disastrous results (bug 706684). - * - * - Cancelling a zoom into a pan is handled correctly. - * - * - Starting with three or more fingers down, releasing fingers so that only two are down, and - * then performing a scale gesture is handled correctly. - * - * - It doesn't take pressure into account, which results in smoother scaling. - */ -class SimpleScaleGestureDetector { - private static final String LOGTAG = "GeckoSimpleScaleGestureDetector"; - - private SimpleScaleGestureListener mListener; - private long mLastEventTime; - private boolean mScaleResult; - - /* Information about all pointers that are down. */ - private LinkedList mPointerInfo; - - /** Creates a new gesture detector with the given listener. */ - SimpleScaleGestureDetector(SimpleScaleGestureListener listener) { - mListener = listener; - mPointerInfo = new LinkedList(); - } - - /** Forward touch events to this function. */ - public void onTouchEvent(MotionEvent event) { - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - // If we get ACTION_DOWN while still tracking any pointers, - // something is wrong. Cancel the current gesture and start over. - if (getPointersDown() > 0) - onTouchEnd(event); - onTouchStart(event); - break; - case MotionEvent.ACTION_POINTER_DOWN: - onTouchStart(event); - break; - case MotionEvent.ACTION_MOVE: - onTouchMove(event); - break; - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - onTouchEnd(event); - break; - } - } - - private int getPointersDown() { - return mPointerInfo.size(); - } - - private int getActionIndex(MotionEvent event) { - return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) - >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - - private void onTouchStart(MotionEvent event) { - mLastEventTime = event.getEventTime(); - mPointerInfo.addFirst(PointerInfo.create(event, getActionIndex(event))); - if (getPointersDown() == 2) { - sendScaleGesture(EventType.BEGIN); - } - } - - private void onTouchMove(MotionEvent event) { - mLastEventTime = event.getEventTime(); - for (int i = 0; i < event.getPointerCount(); i++) { - PointerInfo pointerInfo = pointerInfoForEventIndex(event, i); - if (pointerInfo != null) { - pointerInfo.populate(event, i); - } - } - - if (getPointersDown() == 2) { - sendScaleGesture(EventType.CONTINUE); - } - } - - private void onTouchEnd(MotionEvent event) { - mLastEventTime = event.getEventTime(); - - int action = event.getAction() & MotionEvent.ACTION_MASK; - boolean isCancel = (action == MotionEvent.ACTION_CANCEL || - action == MotionEvent.ACTION_DOWN); - - int id = event.getPointerId(getActionIndex(event)); - ListIterator iterator = mPointerInfo.listIterator(); - while (iterator.hasNext()) { - PointerInfo pointerInfo = iterator.next(); - if (!(isCancel || pointerInfo.getId() == id)) { - continue; - } - - // One of the pointers we were tracking was lifted. Remove its info object from the - // list, recycle it to avoid GC pauses, and send an onScaleEnd() notification if this - // ended the gesture. - iterator.remove(); - pointerInfo.recycle(); - if (getPointersDown() == 1) { - sendScaleGesture(EventType.END); - } - } - } - - /** - * Returns the X coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusX() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().x; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().x + pointerB.getCurrent().x) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusX()!"); - return 0.0f; - } - - /** - * Returns the Y coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusY() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().y; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().y + pointerB.getCurrent().y) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusY()!"); - return 0.0f; - } - - /** Returns the most recent distance between the two pointers. */ - public float getCurrentSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getCurrentSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return PointUtils.distance(pointerA.getCurrent(), pointerB.getCurrent()); - } - - /** Returns the second most recent distance between the two pointers. */ - public float getPreviousSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getPreviousSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - PointF a = pointerA.getPrevious(), b = pointerB.getPrevious(); - if (a == null || b == null) { - a = pointerA.getCurrent(); - b = pointerB.getCurrent(); - } - - return PointUtils.distance(a, b); - } - - /** Returns the time of the last event related to the gesture. */ - public long getEventTime() { - return mLastEventTime; - } - - /** Returns true if the scale gesture is in progress and false otherwise. */ - public boolean isInProgress() { - return getPointersDown() == 2; - } - - /* Sends the requested scale gesture notification to the listener. */ - private void sendScaleGesture(EventType eventType) { - switch (eventType) { - case BEGIN: - mScaleResult = mListener.onScaleBegin(this); - break; - case CONTINUE: - if (mScaleResult) { - mListener.onScale(this); - } - break; - case END: - if (mScaleResult) { - mListener.onScaleEnd(this); - } - break; - } - } - - /* - * Returns the pointer info corresponding to the given pointer index, or null if the pointer - * isn't one that's being tracked. - */ - private PointerInfo pointerInfoForEventIndex(MotionEvent event, int index) { - int id = event.getPointerId(index); - for (PointerInfo pointerInfo : mPointerInfo) { - if (pointerInfo.getId() == id) { - return pointerInfo; - } - } - return null; - } - - private enum EventType { - BEGIN, - CONTINUE, - END, - } - - /* Encapsulates information about one of the two fingers involved in the gesture. */ - private static class PointerInfo { - /* A free list that recycles pointer info objects, to reduce GC pauses. */ - private static Stack sPointerInfoFreeList; - - private int mId; - private PointF mCurrent, mPrevious; - - private PointerInfo() { - // External users should use create() instead. - } - - /* Creates or recycles a new PointerInfo instance from an event and a pointer index. */ - public static PointerInfo create(MotionEvent event, int index) { - if (sPointerInfoFreeList == null) { - sPointerInfoFreeList = new Stack(); - } - - PointerInfo pointerInfo; - if (sPointerInfoFreeList.empty()) { - pointerInfo = new PointerInfo(); - } else { - pointerInfo = sPointerInfoFreeList.pop(); - } - - pointerInfo.populate(event, index); - return pointerInfo; - } - - /* - * Fills in the fields of this instance from the given motion event and pointer index - * within that event. - */ - public void populate(MotionEvent event, int index) { - mId = event.getPointerId(index); - mPrevious = mCurrent; - mCurrent = new PointF(event.getX(index), event.getY(index)); - } - - public void recycle() { - mId = -1; - mPrevious = mCurrent = null; - sPointerInfoFreeList.push(this); - } - - public int getId() { return mId; } - public PointF getCurrent() { return mCurrent; } - public PointF getPrevious() { return mPrevious; } - - @Override - public String toString() { - if (mId == -1) { - return "(up)"; - } - - try { - String prevString; - if (mPrevious == null) { - prevString = "n/a"; - } else { - prevString = PointUtils.toJSON(mPrevious).toString(); - } - - // The current position should always be non-null. - String currentString = PointUtils.toJSON(mCurrent).toString(); - return "id=" + mId + " cur=" + currentString + " prev=" + prevString; - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - public static interface SimpleScaleGestureListener { - public boolean onScale(SimpleScaleGestureDetector detector); - public boolean onScaleBegin(SimpleScaleGestureDetector detector); - public void onScaleEnd(SimpleScaleGestureDetector detector); - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java deleted file mode 100644 index 4b29c515271a..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java +++ /dev/null @@ -1,153 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; -import android.graphics.RegionIterator; -import android.opengl.GLES20; - -import java.nio.FloatBuffer; - -/** - * Encapsulates the logic needed to draw a single textured tile. - * - * TODO: Repeating textures really should be their own type of layer. - */ -public class SingleTileLayer extends TileLayer { - private static final String LOGTAG = "GeckoSingleTileLayer"; - - private Rect mMask; - - // To avoid excessive GC, declare some objects here that would otherwise - // be created and destroyed frequently during draw(). - private final RectF mBounds; - private final RectF mTextureBounds; - private final RectF mViewport; - private final Rect mIntBounds; - private final Rect mSubRect; - private final RectF mSubRectF; - private final Region mMaskedBounds; - private final Rect mCropRect; - private final RectF mObjRectF; - private final float[] mCoords; - - public SingleTileLayer(CairoImage image) { - this(false, image); - } - - public SingleTileLayer(boolean repeat, CairoImage image) { - this(image, repeat ? PaintMode.REPEAT : PaintMode.NORMAL); - } - - public SingleTileLayer(CairoImage image, PaintMode paintMode) { - super(image, paintMode); - - mBounds = new RectF(); - mTextureBounds = new RectF(); - mViewport = new RectF(); - mIntBounds = new Rect(); - mSubRect = new Rect(); - mSubRectF = new RectF(); - mMaskedBounds = new Region(); - mCropRect = new Rect(); - mObjRectF = new RectF(); - mCoords = new float[20]; - } - - /** - * Set an area to mask out when rendering. - */ - public void setMask(Rect aMaskRect) { - mMask = aMaskRect; - } - - @Override - public void draw(RenderContext context) { - // mTextureIDs may be null here during startup if Layer.java's draw method - // failed to acquire the transaction lock and call performUpdates. - if (!initialized()) - return; - - mViewport.set(context.viewport); - - if (repeats()) { - // If we're repeating, we want to adjust the texture bounds so that - // the texture repeats the correct number of times when drawn at - // the size of the viewport. - mBounds.set(getBounds(context)); - mTextureBounds.set(0.0f, 0.0f, mBounds.width(), mBounds.height()); - mBounds.set(0.0f, 0.0f, mViewport.width(), mViewport.height()); - } else if (stretches()) { - // If we're stretching, we just want the bounds and texture bounds - // to fit to the page. - mBounds.set(context.pageRect); - mTextureBounds.set(mBounds); - } else { - mBounds.set(getBounds(context)); - mTextureBounds.set(mBounds); - } - - mBounds.roundOut(mIntBounds); - mMaskedBounds.set(mIntBounds); - if (mMask != null) { - mMaskedBounds.op(mMask, Region.Op.DIFFERENCE); - if (mMaskedBounds.isEmpty()) - return; - } - - // XXX Possible optimisation here, form this array so we can draw it in - // a single call. - RegionIterator i = new RegionIterator(mMaskedBounds); - while (i.next(mSubRect)) { - // Compensate for rounding errors at the edge of the tile caused by - // the roundOut above - mSubRectF.set(Math.max(mBounds.left, (float)mSubRect.left), - Math.max(mBounds.top, (float)mSubRect.top), - Math.min(mBounds.right, (float)mSubRect.right), - Math.min(mBounds.bottom, (float)mSubRect.bottom)); - - // This is the left/top/right/bottom of the rect, relative to the - // bottom-left of the layer, to use for texture coordinates. - mCropRect.set(Math.round(mSubRectF.left - mBounds.left), - Math.round(mBounds.bottom - mSubRectF.top), - Math.round(mSubRectF.right - mBounds.left), - Math.round(mBounds.bottom - mSubRectF.bottom)); - - mObjRectF.set(mSubRectF.left - mViewport.left, - mViewport.bottom - mSubRectF.bottom, - mSubRectF.right - mViewport.left, - mViewport.bottom - mSubRectF.top); - - fillRectCoordBuffer(mCoords, mObjRectF, mViewport.width(), mViewport.height(), - mCropRect, mTextureBounds.width(), mTextureBounds.height()); - - FloatBuffer coordBuffer = context.coordBuffer; - int positionHandle = context.positionHandle; - int textureHandle = context.textureHandle; - - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID()); - - // Make sure we are at position zero in the buffer - coordBuffer.position(0); - coordBuffer.put(mCoords); - - // Unbind any the current array buffer so we can use client side buffers - GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java deleted file mode 100644 index b581d3147ec1..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/SubdocumentScrollHelper.java +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; -import org.mozilla.gecko.util.EventDispatcher; -import org.mozilla.gecko.util.GeckoEventListener; - -import org.json.JSONException; -import org.json.JSONObject; - -import android.graphics.PointF; -import android.os.Handler; -import android.util.Log; - -class SubdocumentScrollHelper implements GeckoEventListener { - private static final String LOGTAG = "GeckoSubdocScroll"; - - private static String MESSAGE_PANNING_OVERRIDE = "Panning:Override"; - private static String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride"; - private static String MESSAGE_SCROLL = "Gesture:Scroll"; - private static String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck"; - - private final Handler mUiHandler; - private final EventDispatcher mEventDispatcher; - - /* This is the amount of displacement we have accepted but not yet sent to JS; this is - * only valid when mOverrideScrollPending is true. */ - private final PointF mPendingDisplacement; - - /* When this is true, we're sending scroll events to JS to scroll the active subdocument. */ - private boolean mOverridePanning; - - /* When this is true, we have received an ack for the last scroll event we sent to JS, and - * are ready to send the next scroll event. Note we only ever have one scroll event inflight - * at a time. */ - private boolean mOverrideScrollAck; - - /* When this is true, we have a pending scroll that we need to send to JS; we were unable - * to send it when it was initially requested because mOverrideScrollAck was not true. */ - private boolean mOverrideScrollPending; - - /* When this is true, the last scroll event we sent actually did some amount of scrolling on - * the subdocument; we use this to decide when we have reached the end of the subdocument. */ - private boolean mScrollSucceeded; - - SubdocumentScrollHelper(EventDispatcher eventDispatcher) { - // mUiHandler will be bound to the UI thread since that's where this constructor runs - mUiHandler = new Handler(); - mPendingDisplacement = new PointF(); - - mEventDispatcher = eventDispatcher; - registerEventListener(MESSAGE_PANNING_OVERRIDE); - registerEventListener(MESSAGE_CANCEL_OVERRIDE); - registerEventListener(MESSAGE_SCROLL_ACK); - } - - void destroy() { - unregisterEventListener(MESSAGE_PANNING_OVERRIDE); - unregisterEventListener(MESSAGE_CANCEL_OVERRIDE); - unregisterEventListener(MESSAGE_SCROLL_ACK); - } - - private void registerEventListener(String event) { - mEventDispatcher.registerEventListener(event, this); - } - - private void unregisterEventListener(String event) { - mEventDispatcher.unregisterEventListener(event, this); - } - - boolean scrollBy(PointF displacement) { - if (! mOverridePanning) { - return false; - } - - if (! mOverrideScrollAck) { - mOverrideScrollPending = true; - mPendingDisplacement.x += displacement.x; - mPendingDisplacement.y += displacement.y; - return true; - } - - JSONObject json = new JSONObject(); - try { - json.put("x", displacement.x); - json.put("y", displacement.y); - } catch (JSONException e) { - Log.e(LOGTAG, "Error forming subwindow scroll message: ", e); - } - //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString())); - - mOverrideScrollAck = false; - mOverrideScrollPending = false; - // clear the |mPendingDisplacement| after serializing |displacement| to - // JSON because they might be the same object - mPendingDisplacement.x = 0; - mPendingDisplacement.y = 0; - - return true; - } - - void cancel() { - mOverridePanning = false; - } - - boolean scrolling() { - return mOverridePanning; - } - - boolean lastScrollSucceeded() { - return mScrollSucceeded; - } - - // GeckoEventListener implementation - - @Override - public void handleMessage(final String event, final JSONObject message) { - // This comes in on the Gecko thread; hand off the handling to the UI thread. - mUiHandler.post(new Runnable() { - @Override - public void run() { - try { - if (MESSAGE_PANNING_OVERRIDE.equals(event)) { - mOverridePanning = true; - mOverrideScrollAck = true; - mOverrideScrollPending = false; - mScrollSucceeded = true; - } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) { - mOverridePanning = false; - } else if (MESSAGE_SCROLL_ACK.equals(event)) { - mOverrideScrollAck = true; - mScrollSucceeded = message.getBoolean("scrolled"); - if (mOverridePanning && mOverrideScrollPending) { - scrollBy(mPendingDisplacement); - } - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message", e); - } - } - }); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java deleted file mode 100644 index c8eb99cb4a88..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.mozglue.DirectBufferAllocator; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Typeface; - -import java.nio.ByteBuffer; - -/** - * Draws text on a layer. This is used for the frame rate meter. - */ -public class TextLayer extends SingleTileLayer { - private final ByteBuffer mBuffer; // this buffer is owned by the BufferedCairoImage - private final IntSize mSize; - - /* - * This awkward pattern is necessary due to Java's restrictions on when one can call superclass - * constructors. - */ - private TextLayer(ByteBuffer buffer, BufferedCairoImage image, IntSize size, String text) { - super(false, image); - mBuffer = buffer; - mSize = size; - renderText(text); - } - - public static TextLayer create(IntSize size, String text) { - ByteBuffer buffer = DirectBufferAllocator.allocate(size.width * size.height * 4); - BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height, - CairoImage.FORMAT_ARGB32); - return new TextLayer(buffer, image, size, text); - } - - public void setText(String text) { - renderText(text); - invalidate(); - } - - private void renderText(String text) { - Bitmap bitmap = Bitmap.createBitmap(mSize.width, mSize.height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - Paint textPaint = new Paint(); - textPaint.setAntiAlias(true); - textPaint.setColor(Color.WHITE); - textPaint.setFakeBoldText(true); - textPaint.setTextSize(18.0f); - textPaint.setTypeface(Typeface.DEFAULT_BOLD); - float width = textPaint.measureText(text) + 18.0f; - - Paint backgroundPaint = new Paint(); - backgroundPaint.setColor(Color.argb(127, 0, 0, 0)); - canvas.drawRect(0.0f, 0.0f, width, 18.0f + 6.0f, backgroundPaint); - - canvas.drawText(text, 6.0f, 18.0f, textPaint); - - bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer()); - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java deleted file mode 100644 index 239ba7bf7694..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.opengl.GLES20; -import android.util.Log; - -import java.util.concurrent.ArrayBlockingQueue; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLContext; - -public class TextureGenerator { - private static final String LOGTAG = "TextureGenerator"; - private static final int POOL_SIZE = 5; - - private static TextureGenerator sSharedInstance; - - private ArrayBlockingQueue mTextureIds; - private EGLContext mContext; - - private TextureGenerator() { mTextureIds = new ArrayBlockingQueue(POOL_SIZE); } - - public static TextureGenerator get() { - if (sSharedInstance == null) - sSharedInstance = new TextureGenerator(); - return sSharedInstance; - } - - public synchronized int take() { - try { - // Will block until one becomes available - return (int)mTextureIds.take(); - } catch (InterruptedException e) { - return 0; - } - } - - public synchronized void fill() { - EGL10 egl = (EGL10)EGLContext.getEGL(); - EGLContext context = egl.eglGetCurrentContext(); - - if (mContext != null && mContext != context) { - mTextureIds.clear(); - } - - mContext = context; - - int numNeeded = mTextureIds.remainingCapacity(); - if (numNeeded == 0) - return; - - // Clear existing GL errors - int error; - while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { - Log.w(LOGTAG, String.format("Clearing GL error: %#x", error)); - } - - int[] textures = new int[numNeeded]; - GLES20.glGenTextures(numNeeded, textures, 0); - - error = GLES20.glGetError(); - if (error != GLES20.GL_NO_ERROR) { - Log.e(LOGTAG, String.format("Failed to generate textures: %#x", error), new Exception()); - return; - } - - for (int i = 0; i < numNeeded; i++) { - mTextureIds.offer(textures[i]); - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java deleted file mode 100644 index 71b4690eb9f1..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.opengl.GLES20; - -import java.util.ArrayList; - -/** Manages a list of dead tiles, so we don't leak resources. */ -public class TextureReaper { - private static TextureReaper sSharedInstance; - private ArrayList mDeadTextureIDs; - - private TextureReaper() { mDeadTextureIDs = new ArrayList(); } - - public static TextureReaper get() { - if (sSharedInstance == null) - sSharedInstance = new TextureReaper(); - return sSharedInstance; - } - - public void add(int[] textureIDs) { - for (int textureID : textureIDs) - add(textureID); - } - - public void add(int textureID) { - mDeadTextureIDs.add(textureID); - } - - public void reap() { - int numTextures = mDeadTextureIDs.size(); - // Adreno 200 will generate INVALID_VALUE if len == 0 is passed to glDeleteTextures, - // even though it's not supposed to. - if (numTextures == 0) - return; - - int[] deadTextureIDs = new int[numTextures]; - for (int i = 0; i < numTextures; i++) { - deadTextureIDs[i] = mDeadTextureIDs.get(i); - } - mDeadTextureIDs.clear(); - - GLES20.glDeleteTextures(deadTextureIDs.length, deadTextureIDs, 0); - } -} - - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java deleted file mode 100644 index 3c3bc2887109..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java +++ /dev/null @@ -1,177 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Rect; -import android.opengl.GLES20; -import android.util.Log; - -import java.nio.ByteBuffer; - -/** - * Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL - * ES. - */ -public abstract class TileLayer extends Layer { - private static final String LOGTAG = "GeckoTileLayer"; - - private final Rect mDirtyRect; - private IntSize mSize; - private int[] mTextureIDs; - - protected final CairoImage mImage; - - public enum PaintMode { NORMAL, REPEAT, STRETCH }; - private PaintMode mPaintMode; - - public TileLayer(CairoImage image, PaintMode paintMode) { - super(image.getSize()); - - mPaintMode = paintMode; - mImage = image; - mSize = new IntSize(0, 0); - mDirtyRect = new Rect(); - } - - protected boolean repeats() { return mPaintMode == PaintMode.REPEAT; } - protected boolean stretches() { return mPaintMode == PaintMode.STRETCH; } - protected int getTextureID() { return mTextureIDs[0]; } - protected boolean initialized() { return mImage != null && mTextureIDs != null; } - - @Override - protected void finalize() throws Throwable { - try { - if (mTextureIDs != null) - TextureReaper.get().add(mTextureIDs); - } finally { - super.finalize(); - } - } - - public void destroy() { - try { - if (mImage != null) { - mImage.destroy(); - } - } catch (Exception ex) { - Log.e(LOGTAG, "error clearing buffers: ", ex); - } - } - - public void setPaintMode(PaintMode mode) { - mPaintMode = mode; - } - - /** - * Invalidates the entire buffer so that it will be uploaded again. Only valid inside a - * transaction. - */ - - public void invalidate() { - if (!inTransaction()) - throw new RuntimeException("invalidate() is only valid inside a transaction"); - IntSize bufferSize = mImage.getSize(); - mDirtyRect.set(0, 0, bufferSize.width, bufferSize.height); - } - - private void validateTexture() { - /* Calculate the ideal texture size. This must be a power of two if - * the texture is repeated or OpenGL ES 2.0 isn't supported, as - * OpenGL ES 2.0 is required for NPOT texture support (without - * extensions), but doesn't support repeating NPOT textures. - * - * XXX Currently, we don't pick a GLES 2.0 context, so always round. - */ - IntSize textureSize = mImage.getSize().nextPowerOfTwo(); - - if (!textureSize.equals(mSize)) { - mSize = textureSize; - - // Delete the old texture - if (mTextureIDs != null) { - TextureReaper.get().add(mTextureIDs); - mTextureIDs = null; - - // Free the texture immediately, so we don't incur a - // temporarily increased memory usage. - TextureReaper.get().reap(); - } - } - } - - @Override - protected void performUpdates(RenderContext context) { - super.performUpdates(context); - - // Reallocate the texture if the size has changed - validateTexture(); - - // Don't do any work if the image has an invalid size. - if (!mImage.getSize().isPositive()) - return; - - // If we haven't allocated a texture, assume the whole region is dirty - if (mTextureIDs == null) { - uploadFullTexture(); - } else { - uploadDirtyRect(mDirtyRect); - } - - mDirtyRect.setEmpty(); - } - - private void uploadFullTexture() { - IntSize bufferSize = mImage.getSize(); - uploadDirtyRect(new Rect(0, 0, bufferSize.width, bufferSize.height)); - } - - private void uploadDirtyRect(Rect dirtyRect) { - // If we have nothing to upload, just return for now - if (dirtyRect.isEmpty()) - return; - - // It's possible that the buffer will be null, check for that and return - ByteBuffer imageBuffer = mImage.getBuffer(); - if (imageBuffer == null) - return; - - if (mTextureIDs == null) { - mTextureIDs = new int[1]; - GLES20.glGenTextures(mTextureIDs.length, mTextureIDs, 0); - } - - int cairoFormat = mImage.getFormat(); - CairoGLInfo glInfo = new CairoGLInfo(cairoFormat); - - bindAndSetGLParameters(); - - // XXX TexSubImage2D is too broken to rely on Adreno, and very slow - // on other chipsets, so we always upload the entire buffer. - IntSize bufferSize = mImage.getSize(); - if (mSize.equals(bufferSize)) { - GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, - mSize.height, 0, glInfo.format, glInfo.type, imageBuffer); - } else { - // Our texture has been expanded to the next power of two. - // XXX We probably never want to take this path, so throw an exception. - throw new RuntimeException("Buffer/image size mismatch in TileLayer!"); - } - } - - private void bindAndSetGLParameters() { - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, - GLES20.GL_LINEAR); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, - GLES20.GL_LINEAR); - - int repeatMode = repeats() ? GLES20.GL_REPEAT : GLES20.GL_CLAMP_TO_EDGE; - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, repeatMode); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, repeatMode); - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java deleted file mode 100644 index 9710bd41df5f..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/TouchEventHandler.java +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.Tab; -//import org.mozilla.gecko.Tabs; - -import android.content.Context; -import android.os.SystemClock; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; - -import java.util.LinkedList; -import java.util.Queue; - -/** - * This class handles incoming touch events from the user and sends them to - * listeners in Gecko and/or performs the "default action" (asynchronous pan/zoom - * behaviour. EVERYTHING IN THIS CLASS MUST RUN ON THE UI THREAD. - * - * In the following code/comments, a "block" of events refers to a contiguous - * sequence of events that starts with a DOWN or POINTER_DOWN and goes up to - * but not including the next DOWN or POINTER_DOWN event. - * - * "Dispatching" an event refers to performing the default actions for the event, - * which at our level of abstraction just means sending it off to the gesture - * detectors and the pan/zoom controller. - * - * If an event is "default-prevented" that means one or more listeners in Gecko - * has called preventDefault() on the event, which means that the default action - * for that event should not occur. Usually we care about a "block" of events being - * default-prevented, which means that the DOWN/POINTER_DOWN event that started - * the block, or the first MOVE event following that, were prevent-defaulted. - * - * A "default-prevented notification" is when we here in Java-land receive a notification - * from gecko as to whether or not a block of events was default-prevented. This happens - * at some point after the first or second event in the block is processed in Gecko. - * This code assumes we get EXACTLY ONE default-prevented notification for each block - * of events. - * - * Note that even if all events are default-prevented, we still send specific types - * of notifications to the pan/zoom controller. The notifications are needed - * to respond to user actions a timely manner regardless of default-prevention, - * and fix issues like bug 749384. - */ -final class TouchEventHandler /*implements Tabs.OnTabsChangedListener*/ { - private static final String LOGTAG = "GeckoTouchEventHandler"; - - // The time limit for listeners to respond with preventDefault on touchevents - // before we begin panning the page - private final int EVENT_LISTENER_TIMEOUT = 200; - - private final View mView; - private final GestureDetector mGestureDetector; - private final SimpleScaleGestureDetector mScaleGestureDetector; - private final JavaPanZoomController mPanZoomController; - - // the queue of events that we are holding on to while waiting for a preventDefault - // notification - private final Queue mEventQueue; - private final ListenerTimeoutProcessor mListenerTimeoutProcessor; - - // whether or not we should wait for touch listeners to respond (this state is - // per-tab and is updated when we switch tabs). - private boolean mWaitForTouchListeners; - - // true if we should hold incoming events in our queue. this is re-set for every - // block of events, this is cleared once we find out if the block has been - // default-prevented or not (or we time out waiting for that). - private boolean mHoldInQueue; - - // false if the current event block has been default-prevented. In this case, - // we still pass the event to both Gecko and the pan/zoom controller, but the - // latter will not use it to scroll content. It may still use the events for - // other things, such as making the dynamic toolbar visible. - private boolean mAllowDefaultAction; - - // this next variable requires some explanation. strap yourself in. - // - // for each block of events, we do two things: (1) send the events to gecko and expect - // exactly one default-prevented notification in return, and (2) kick off a delayed - // ListenerTimeoutProcessor that triggers in case we don't hear from the listener in - // a timely fashion. - // since events are constantly coming in, we need to be able to handle more than one - // block of events in the queue. - // - // this means that there are ordering restrictions on these that we can take advantage of, - // and need to abide by. blocks of events in the queue will always be in the order that - // the user generated them. default-prevented notifications we get from gecko will be in - // the same order as the blocks of events in the queue. the ListenerTimeoutProcessors that - // have been posted will also fire in the same order as the blocks of events in the queue. - // HOWEVER, we may get multiple default-prevented notifications interleaved with multiple - // ListenerTimeoutProcessor firings, and that interleaving is not predictable. - // - // therefore, we need to make sure that for each block of events, we process the queued - // events exactly once, either when we get the default-prevented notification, or when the - // timeout expires (whichever happens first). there is no way to associate the - // default-prevented notification with a particular block of events other than via ordering, - // - // so what we do to accomplish this is to track a "processing balance", which is the number - // of default-prevented notifications that we have received, minus the number of ListenerTimeoutProcessors - // that have fired. (think "balance" as in teeter-totter balance). this value is: - // - zero when we are in a state where the next default-prevented notification we expect - // to receive and the next ListenerTimeoutProcessor we expect to fire both correspond to - // the next block of events in the queue. - // - positive when we are in a state where we have received more default-prevented notifications - // than ListenerTimeoutProcessors. This means that the next default-prevented notification - // does correspond to the block at the head of the queue, but the next n ListenerTimeoutProcessors - // need to be ignored as they are for blocks we have already processed. (n is the absolute value - // of the balance.) - // - negative when we are in a state where we have received more ListenerTimeoutProcessors than - // default-prevented notifications. This means that the next ListenerTimeoutProcessor that - // we receive does correspond to the block at the head of the queue, but the next n - // default-prevented notifications need to be ignored as they are for blocks we have already - // processed. (n is the absolute value of the balance.) - private int mProcessingBalance; - - TouchEventHandler(Context context, View view, JavaPanZoomController panZoomController) { - mView = view; - - mEventQueue = new LinkedList(); - mPanZoomController = panZoomController; - mGestureDetector = new GestureDetector(context, mPanZoomController); - mScaleGestureDetector = new SimpleScaleGestureDetector(mPanZoomController); - mListenerTimeoutProcessor = new ListenerTimeoutProcessor(); - mAllowDefaultAction = true; - - mGestureDetector.setOnDoubleTapListener(mPanZoomController); - - //Tabs.registerOnTabsChangedListener(this); - } - - public void destroy() { - //Tabs.unregisterOnTabsChangedListener(this); - } - - /* This function MUST be called on the UI thread */ - public boolean handleEvent(MotionEvent event) { - if (isDownEvent(event)) { - // this is the start of a new block of events! whee! - mHoldInQueue = mWaitForTouchListeners; - - // Set mAllowDefaultAction to true so that in the event we dispatch events, the - // PanZoomController doesn't treat them as if they've been prevent-defaulted - // when they haven't. - mAllowDefaultAction = true; - if (mHoldInQueue) { - // if the new block we are starting is the current block (i.e. there are no - // other blocks waiting in the queue, then we should let the pan/zoom controller - // know we are waiting for the touch listeners to run - if (mEventQueue.isEmpty()) { - mPanZoomController.startingNewEventBlock(event, true); - } - } else { - // we're not going to be holding this block of events in the queue, but we need - // a marker of some sort so that the processEventBlock loop deals with the blocks - // in the right order as notifications come in. we use a single null event in - // the queue as a placeholder for a block of events that has already been dispatched. - mEventQueue.add(null); - mPanZoomController.startingNewEventBlock(event, false); - } - - // set the timeout so that we dispatch these events and update mProcessingBalance - // if we don't get a default-prevented notification - mView.postDelayed(mListenerTimeoutProcessor, EVENT_LISTENER_TIMEOUT); - } - - // if we need to hold the events, add it to the queue, otherwise dispatch - // it directly. - if (mHoldInQueue) { - mEventQueue.add(MotionEvent.obtain(event)); - } else { - dispatchEvent(event, mAllowDefaultAction); - } - - return false; - } - - /** - * This function is how gecko sends us a default-prevented notification. It is called - * once gecko knows definitively whether the block of events has had preventDefault - * called on it (either on the initial down event that starts the block, or on - * the first event following that down event). - * - * This function MUST be called on the UI thread. - */ - public void handleEventListenerAction(boolean allowDefaultAction) { - if (mProcessingBalance > 0) { - // this event listener that triggered this took too long, and the corresponding - // ListenerTimeoutProcessor runnable already ran for the event in question. the - // block of events this is for has already been processed, so we don't need to - // do anything here. - } else { - processEventBlock(allowDefaultAction); - } - mProcessingBalance--; - } - - /* This function MUST be called on the UI thread. */ - public void setWaitForTouchListeners(boolean aValue) { - mWaitForTouchListeners = aValue; - } - - private boolean isDownEvent(MotionEvent event) { - int action = (event.getAction() & MotionEvent.ACTION_MASK); - return (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN); - } - - private boolean touchFinished(MotionEvent event) { - int action = (event.getAction() & MotionEvent.ACTION_MASK); - return (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL); - } - - /** - * Dispatch the event to the gesture detectors and the pan/zoom controller. - */ - private void dispatchEvent(MotionEvent event, boolean allowDefaultAction) { - if (allowDefaultAction) { - if (mGestureDetector.onTouchEvent(event)) { - return; - } - mScaleGestureDetector.onTouchEvent(event); - if (mScaleGestureDetector.isInProgress()) { - return; - } - } - mPanZoomController.handleEvent(event, !allowDefaultAction); - } - - /** - * Process the block of events at the head of the queue now that we know - * whether it has been default-prevented or not. - */ - private void processEventBlock(boolean allowDefaultAction) { - if (mEventQueue.isEmpty()) { - Log.e(LOGTAG, "Unexpected empty event queue in processEventBlock!", new Exception()); - return; - } - - // the odd loop condition is because the first event in the queue will - // always be a DOWN or POINTER_DOWN event, and we want to process all - // the events in the queue starting at that one, up to but not including - // the next DOWN or POINTER_DOWN event. - - MotionEvent event = mEventQueue.poll(); - while (true) { - // event being null here is valid and represents a block of events - // that has already been dispatched. - - if (event != null) { - dispatchEvent(event, allowDefaultAction); - } - if (mEventQueue.isEmpty()) { - // we have processed the backlog of events, and are all caught up. - // now we can set clear the hold flag and set the dispatch flag so - // that the handleEvent() function can do the right thing for all - // remaining events in this block (which is still ongoing) without - // having to put them in the queue. - mHoldInQueue = false; - mAllowDefaultAction = allowDefaultAction; - break; - } - event = mEventQueue.peek(); - if (event == null || isDownEvent(event)) { - // we have finished processing the block we were interested in. - // now we wait for the next call to processEventBlock - if (event != null) { - mPanZoomController.startingNewEventBlock(event, true); - } - break; - } - // pop the event we peeked above, as it is still part of the block and - // we want to keep processing - mEventQueue.remove(); - } - } - - private class ListenerTimeoutProcessor implements Runnable { - /* This MUST be run on the UI thread */ - @Override - public void run() { - if (mProcessingBalance < 0) { - // gecko already responded with default-prevented notification, and so - // the block of events this ListenerTimeoutProcessor corresponds to have - // already been removed from the queue. - } else { - processEventBlock(true); - } - mProcessingBalance++; - } - } - - // Tabs.OnTabsChangedListener implementation - - /*@Override - public void onTabChanged(Tab tab, Tabs.TabEvents msg, Object data) { - if ((Tabs.getInstance().isSelectedTab(tab) && msg == Tabs.TabEvents.STOP) || msg == Tabs.TabEvents.SELECTED) { - mWaitForTouchListeners = tab.getHasTouchListeners(); - } - }*/ -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java deleted file mode 100644 index 97ca109f118d..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java +++ /dev/null @@ -1,34 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.mozglue.generatorannotations.WrapEntireClassForJNI; - -//@WrapEntireClassForJNI -public class ViewTransform { - public float x; - public float y; - public float scale; - public float fixedLayerMarginLeft; - public float fixedLayerMarginTop; - public float fixedLayerMarginRight; - public float fixedLayerMarginBottom; - public float offsetX; - public float offsetY; - - public ViewTransform(float inX, float inY, float inScale) { - x = inX; - y = inY; - scale = inScale; - fixedLayerMarginLeft = 0; - fixedLayerMarginTop = 0; - fixedLayerMarginRight = 0; - fixedLayerMarginBottom = 0; - offsetX = 0; - offsetY = 0; - } -} - diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java deleted file mode 100644 index 83d012876176..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java +++ /dev/null @@ -1,36 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.gfx; - -public class VirtualLayer extends Layer { - public VirtualLayer(IntSize size) { - super(size); - } - - @Override - public void draw(RenderContext context) { - // No-op. - } - - void setPositionAndResolution(int left, int top, int right, int bottom, float newResolution) { - // This is an optimized version of the following code: - // beginTransaction(); - // try { - // setPosition(new Rect(left, top, right, bottom)); - // setResolution(newResolution); - // performUpdates(null); - // } finally { - // endTransaction(); - // } - - // it is safe to drop the transaction lock in this instance (i.e. for the - // VirtualLayer that is just a shadow of what gecko is painting) because - // the position and resolution of this layer are always touched on the compositor - // thread, and therefore do not require synchronization. - mPosition.set(left, top, right, bottom); - mResolution = newResolution; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java deleted file mode 100644 index 61444e6cfc47..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/mozglue/DirectBufferAllocator.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.mozglue; - -import java.nio.ByteBuffer; - -// -// We must manually allocate direct buffers in JNI to work around a bug where Honeycomb's -// ByteBuffer.allocateDirect() grossly overallocates the direct buffer size. -// https://code.google.com/p/android/issues/detail?id=16941 -// - -public final class DirectBufferAllocator { - private DirectBufferAllocator() {} - - public static ByteBuffer allocate(int size) { - if (size <= 0) { - throw new IllegalArgumentException("Invalid size " + size); - } - - ByteBuffer directBuffer = ByteBuffer.allocateDirect(size); - //ByteBuffer directBuffer = nativeAllocateDirectBuffer(size); - if (directBuffer == null) { - throw new OutOfMemoryError("allocateDirectBuffer() returned null"); - } else if (!directBuffer.isDirect()) { - throw new AssertionError("allocateDirectBuffer() did not return a direct buffer"); - } - - return directBuffer; - } - - public static ByteBuffer free(ByteBuffer buffer) { - if (buffer == null) { - return null; - } - - if (!buffer.isDirect()) { - throw new IllegalArgumentException("buffer must be direct"); - } - - //nativeFreeDirectBuffer(buffer); - return null; - } - - // These JNI methods are implemented in mozglue/android/nsGeckoUtils.cpp. - //private static native ByteBuffer nativeAllocateDirectBuffer(long size); - //private static native void nativeFreeDirectBuffer(ByteBuffer buf); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java deleted file mode 100644 index 5b6d50883b42..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/EventDispatcher.java +++ /dev/null @@ -1,115 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import org.json.JSONObject; - -import android.util.Log; - -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CopyOnWriteArrayList; - -public final class EventDispatcher { - private static final String LOGTAG = "GeckoEventDispatcher"; - - private final Map> mEventListeners - = new HashMap>(); - - public void registerEventListener(String event, GeckoEventListener listener) { - synchronized (mEventListeners) { - CopyOnWriteArrayList listeners = mEventListeners.get(event); - if (listeners == null) { - // create a CopyOnWriteArrayList so that we can modify it - // concurrently with iterating through it in handleGeckoMessage. - // Otherwise we could end up throwing a ConcurrentModificationException. - listeners = new CopyOnWriteArrayList(); - } else if (listeners.contains(listener)) { - Log.w(LOGTAG, "EventListener already registered for event '" + event + "'", - new IllegalArgumentException()); - } - listeners.add(listener); - mEventListeners.put(event, listeners); - } - } - - public void unregisterEventListener(String event, GeckoEventListener listener) { - synchronized (mEventListeners) { - CopyOnWriteArrayList listeners = mEventListeners.get(event); - if (listeners == null) { - Log.w(LOGTAG, "unregisterEventListener: event '" + event + "' has no listeners"); - return; - } - if (!listeners.remove(listener)) { - Log.w(LOGTAG, "unregisterEventListener: tried to remove an unregistered listener " + - "for event '" + event + "'"); - } - if (listeners.size() == 0) { - mEventListeners.remove(event); - } - } - } - - public String dispatchEvent(String message) { - try { - JSONObject json = new JSONObject(message); - return dispatchEvent(json); - } catch (Exception e) { - Log.e(LOGTAG, "dispatchEvent: malformed JSON.", e); - } - - return ""; - } - - public String dispatchEvent(JSONObject json) { - // { - // "type": "value", - // "event_specific": "value", - // ... - try { - JSONObject gecko = json.has("gecko") ? json.getJSONObject("gecko") : null; - if (gecko != null) { - json = gecko; - } - - String type = json.getString("type"); - - if (gecko != null) { - Log.w(LOGTAG, "Message '" + type + "' has deprecated 'gecko' property!"); - } - - CopyOnWriteArrayList listeners; - synchronized (mEventListeners) { - listeners = mEventListeners.get(type); - } - - if (listeners == null || listeners.size() == 0) { - Log.d(LOGTAG, "dispatchEvent: no listeners registered for event '" + type + "'"); - return ""; - } - - String response = null; - - for (GeckoEventListener listener : listeners) { - listener.handleMessage(type, json); - if (listener instanceof GeckoEventResponder) { - String newResponse = ((GeckoEventResponder)listener).getResponse(json); - if (response != null && newResponse != null) { - Log.e(LOGTAG, "Received two responses for message of type " + type); - } - response = newResponse; - } - } - - if (response != null) - return response; - - } catch (Exception e) { - Log.e(LOGTAG, "handleGeckoMessage throws " + e, e); - } - - return ""; - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java deleted file mode 100644 index fbcd7254f62b..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import android.graphics.PointF; - -import java.lang.IllegalArgumentException; - -public final class FloatUtils { - private FloatUtils() {} - - public static boolean fuzzyEquals(float a, float b) { - return (Math.abs(a - b) < 1e-6); - } - - public static boolean fuzzyEquals(PointF a, PointF b) { - return fuzzyEquals(a.x, b.x) && fuzzyEquals(a.y, b.y); - } - - /* - * Returns the value that represents a linear transition between `from` and `to` at time `t`, - * which is on the scale [0, 1). Thus with t = 0.0f, this returns `from`; with t = 1.0f, this - * returns `to`; with t = 0.5f, this returns the value halfway from `from` to `to`. - */ - public static float interpolate(float from, float to, float t) { - return from + (to - from) * t; - } - - /** - * Returns 'value', clamped so that it isn't any lower than 'low', and it - * isn't any higher than 'high'. - */ - public static float clamp(float value, float low, float high) { - if (high < low) { - throw new IllegalArgumentException( - "clamp called with invalid parameters (" + high + " < " + low + ")" ); - } - return Math.max(low, Math.min(high, value)); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java deleted file mode 100644 index f7873fe733d3..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoBackgroundThread.java +++ /dev/null @@ -1,55 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import android.os.Handler; -import android.os.Looper; - -import java.util.concurrent.SynchronousQueue; - -final class GeckoBackgroundThread extends Thread { - private static final String LOOPER_NAME = "GeckoBackgroundThread"; - - // Guarded by 'this'. - private static Handler sHandler = null; - private SynchronousQueue mHandlerQueue = new SynchronousQueue(); - - // Singleton, so private constructor. - private GeckoBackgroundThread() { - super(); - } - - @Override - public void run() { - setName(LOOPER_NAME); - Looper.prepare(); - try { - mHandlerQueue.put(new Handler()); - } catch (InterruptedException ie) {} - - Looper.loop(); - } - - // Get a Handler for a looper thread, or create one if it doesn't yet exist. - /*package*/ static synchronized Handler getHandler() { - if (sHandler == null) { - GeckoBackgroundThread lt = new GeckoBackgroundThread(); - ThreadUtils.setBackgroundThread(lt); - lt.start(); - try { - sHandler = lt.mHandlerQueue.take(); - } catch (InterruptedException ie) {} - } - return sHandler; - } - - /*package*/ static void post(Runnable runnable) { - Handler handler = getHandler(); - if (handler == null) { - throw new IllegalStateException("No handler! Must have been interrupted. Not posting."); - } - handler.post(runnable); - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java deleted file mode 100644 index 4d0c313b0c6a..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventListener.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import org.json.JSONObject; -//import org.mozilla.gecko.mozglue.RobocopTarget; - -//@RobocopTarget -public interface GeckoEventListener { - void handleMessage(String event, JSONObject message); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java deleted file mode 100644 index dc4561561c8a..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/GeckoEventResponder.java +++ /dev/null @@ -1,16 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.util; - -import org.json.JSONObject; - -public interface GeckoEventResponder extends GeckoEventListener { - String getResponse(JSONObject response); -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java deleted file mode 100644 index a646f1ae4e9d..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/ThreadUtils.java +++ /dev/null @@ -1,169 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import android.os.Handler; -import android.os.MessageQueue; -import android.util.Log; - -import java.util.Map; - -public final class ThreadUtils { - private static final String LOGTAG = "ThreadUtils"; - - private static Thread sUiThread; - private static Thread sBackgroundThread; - - private static Handler sUiHandler; - - // Referenced directly from GeckoAppShell in highly performance-sensitive code (The extra - // function call of the getter was harming performance. (Bug 897123)) - // Once Bug 709230 is resolved we should reconsider this as ProGuard should be able to optimise - // this out at compile time. - public static Handler sGeckoHandler; - public static MessageQueue sGeckoQueue; - public static Thread sGeckoThread; - - // Delayed Runnable that resets the Gecko thread priority. - private static final Runnable sPriorityResetRunnable = new Runnable() { - @Override - public void run() { - resetGeckoPriority(); - } - }; - - private static boolean sIsGeckoPriorityReduced; - - @SuppressWarnings("serial") - public static class UiThreadBlockedException extends RuntimeException { - public UiThreadBlockedException() { - super(); - } - - public UiThreadBlockedException(String msg) { - super(msg); - } - - public UiThreadBlockedException(String msg, Throwable e) { - super(msg, e); - } - - public UiThreadBlockedException(Throwable e) { - super(e); - } - } - - public static void dumpAllStackTraces() { - Log.w(LOGTAG, "Dumping ALL the threads!"); - Map allStacks = Thread.getAllStackTraces(); - for (Thread t : allStacks.keySet()) { - Log.w(LOGTAG, t.toString()); - for (StackTraceElement ste : allStacks.get(t)) { - Log.w(LOGTAG, ste.toString()); - } - Log.w(LOGTAG, "----"); - } - } - - public static void setUiThread(Thread thread, Handler handler) { - sUiThread = thread; - sUiHandler = handler; - } - - public static void setBackgroundThread(Thread thread) { - sBackgroundThread = thread; - } - - public static Thread getUiThread() { - return sUiThread; - } - - public static Handler getUiHandler() { - return sUiHandler; - } - - public static void postToUiThread(Runnable runnable) { - sUiHandler.post(runnable); - } - - public static Thread getBackgroundThread() { - return sBackgroundThread; - } - - public static Handler getBackgroundHandler() { - return GeckoBackgroundThread.getHandler(); - } - - public static void postToBackgroundThread(Runnable runnable) { - GeckoBackgroundThread.post(runnable); - } - - public static void assertOnUiThread() { - assertOnThread(getUiThread()); - } - - public static void assertOnGeckoThread() { - assertOnThread(sGeckoThread); - } - - public static void assertOnBackgroundThread() { - assertOnThread(getBackgroundThread()); - } - - public static void assertOnThread(Thread expectedThread) { - Thread currentThread = Thread.currentThread(); - long currentThreadId = currentThread.getId(); - long expectedThreadId = expectedThread.getId(); - - if (currentThreadId != expectedThreadId) { - throw new IllegalThreadStateException("Expected thread " + expectedThreadId + " (\"" - + expectedThread.getName() - + "\"), but running on thread " + currentThreadId - + " (\"" + currentThread.getName() + ")"); - } - } - - public static boolean isOnUiThread() { - return isOnThread(getUiThread()); - } - - public static boolean isOnBackgroundThread() { - return isOnThread(sBackgroundThread); - } - - public static boolean isOnThread(Thread thread) { - return (Thread.currentThread().getId() == thread.getId()); - } - - /** - * Reduces the priority of the Gecko thread, allowing other operations - * (such as those related to the UI and database) to take precedence. - * - * Note that there are no guards in place to prevent multiple calls - * to this method from conflicting with each other. - * - * @param timeout Timeout in ms after which the priority will be reset - */ - public static void reduceGeckoPriority(long timeout) { - if (!sIsGeckoPriorityReduced) { - sIsGeckoPriorityReduced = true; - sGeckoThread.setPriority(Thread.MIN_PRIORITY); - getUiHandler().postDelayed(sPriorityResetRunnable, timeout); - } - } - - /** - * Resets the priority of a thread whose priority has been reduced - * by reduceGeckoPriority. - */ - public static void resetGeckoPriority() { - if (sIsGeckoPriorityReduced) { - sIsGeckoPriorityReduced = false; - sGeckoThread.setPriority(Thread.NORM_PRIORITY); - getUiHandler().removeCallbacks(sPriorityResetRunnable); - } - } -} diff --git a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java b/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java deleted file mode 100644 index aee875c33dc9..000000000000 --- a/android/experimental/LOAndroid/app/src/main/java/org/mozilla/gecko/util/UiAsyncTask.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import android.os.Handler; -import android.os.Looper; - -/** - * Executes a background task and publishes the result on the UI thread. - * - * The standard {@link android.os.AsyncTask} only runs onPostExecute on the - * thread it is constructed on, so this is a convenience class for creating - * tasks off the UI thread. - */ -public abstract class UiAsyncTask { - private volatile boolean mCancelled = false; - private final Handler mBackgroundThreadHandler; - private static Handler sHandler; - - /** - * Creates a new asynchronous task. - * - * @param backgroundThreadHandler the handler to execute the background task on - */ - public UiAsyncTask(Handler backgroundThreadHandler) { - mBackgroundThreadHandler = backgroundThreadHandler; - } - - private static synchronized Handler getUiHandler() { - if (sHandler == null) { - sHandler = new Handler(Looper.getMainLooper()); - } - return sHandler; - } - - private final class BackgroundTaskRunnable implements Runnable { - private Params[] mParams; - - public BackgroundTaskRunnable(Params... params) { - mParams = params; - } - - @Override - public void run() { - final Result result = doInBackground(mParams); - - getUiHandler().post(new Runnable() { - @Override - public void run() { - if (mCancelled) - onCancelled(); - else - onPostExecute(result); - } - }); - } - } - - public final void execute(final Params... params) { - getUiHandler().post(new Runnable() { - @Override - public void run() { - onPreExecute(); - mBackgroundThreadHandler.post(new BackgroundTaskRunnable(params)); - } - }); - } - - @SuppressWarnings({"UnusedParameters"}) - public final boolean cancel(boolean mayInterruptIfRunning) { - mCancelled = true; - return mCancelled; - } - - public final boolean isCancelled() { - return mCancelled; - } - - protected void onPreExecute() { } - protected void onPostExecute(Result result) { } - protected void onCancelled() { } - protected abstract Result doInBackground(Params... params); -} diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 96a442e5b8e9..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png deleted file mode 100644 index d5f16694f342..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-hdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047dfa4ed..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png deleted file mode 100644 index 835fc9290727..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-mdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d760f051..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png deleted file mode 100644 index c8005425416a..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-xhdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 4df18946442e..000000000000 Binary files a/android/experimental/LOAndroid/app/src/main/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml b/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 600acdd4b40b..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/android/experimental/LOAndroid/app/src/main/res/menu/main.xml b/android/experimental/LOAndroid/app/src/main/res/menu/main.xml deleted file mode 100644 index 6768fd32a890..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/menu/main.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml b/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc81644461..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/android/experimental/LOAndroid/app/src/main/res/values/colors.xml b/android/experimental/LOAndroid/app/src/main/res/values/colors.xml deleted file mode 100644 index f8e207d4e00e..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - #FFECF0F3 - #FFCED7DE - #FF292C29 - #FF363B40 - #33000000 - #1A000000 - #33FFFFFF - #1AFFFFFF - - - #FF696D71 - - - #FF565B60 - - - #FFA5ACB2 - - - #FFB9C1C7 - - - #FF545654 - - - #FF3F423F - - - - #222222 - #777777 - #9198A1 - - - #FFFFFF - #DDDDDD - #A4A7A9 - - - #999999 - - - #666666 - #7F828A - - - #FF9500 - #D06BFF - - - #22629E - - #000000 - #ffffff - #000000 - #ffffff - - #FF222222 - #FF2AA1FE - #FFD1D5DA - #FFB3C2CE - #FFDDE4EA - - #ffffff - #FFFF9500 - #FFD06BFF - #dddddd - #bbbbbb - #4D000000 - #ffffff - - #FFF - #DDD - #000 - #666 - - #A6A6A6 - #000 - #FFF - #b14646 - #12000000 - - #FFF5F7F9 - - #D1D9E1 - - diff --git a/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml b/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml deleted file mode 100644 index 47c82246738c..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/android/experimental/LOAndroid/app/src/main/res/values/strings.xml b/android/experimental/LOAndroid/app/src/main/res/values/strings.xml deleted file mode 100644 index 8864167560f8..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - LOAndroid - Hello world! - Settings - - diff --git a/android/experimental/LOAndroid/app/src/main/res/values/styles.xml b/android/experimental/LOAndroid/app/src/main/res/values/styles.xml deleted file mode 100644 index ff6c9d2c0fb9..000000000000 --- a/android/experimental/LOAndroid/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/android/experimental/LOAndroid/build.gradle b/android/experimental/LOAndroid/build.gradle deleted file mode 100644 index 80eec1a79307..000000000000 --- a/android/experimental/LOAndroid/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.9.+' - } -} - -allprojects { - repositories { - mavenCentral() - } -} diff --git a/android/experimental/LOAndroid/gradle.properties b/android/experimental/LOAndroid/gradle.properties deleted file mode 100644 index 5d08ba75bb97..000000000000 --- a/android/experimental/LOAndroid/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Settings specified in this file will override any Gradle settings -# configured through the IDE. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar b/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a8698..000000000000 Binary files a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties b/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 5de946b072f1..000000000000 --- a/android/experimental/LOAndroid/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Apr 10 15:27:10 PDT 2013 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip diff --git a/android/experimental/LOAndroid/gradlew b/android/experimental/LOAndroid/gradlew deleted file mode 100644 index 91a7e269e19d..000000000000 --- a/android/experimental/LOAndroid/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/experimental/LOAndroid/gradlew.bat b/android/experimental/LOAndroid/gradlew.bat deleted file mode 100644 index aec99730b4e8..000000000000 --- a/android/experimental/LOAndroid/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/experimental/LOAndroid/settings.gradle b/android/experimental/LOAndroid/settings.gradle deleted file mode 100644 index e7b4def49cb5..000000000000 --- a/android/experimental/LOAndroid/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/android/experimental/LOAndroid2/.gitignore b/android/experimental/LOAndroid2/.gitignore deleted file mode 100644 index d6bfc95b184b..000000000000 --- a/android/experimental/LOAndroid2/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.gradle -/local.properties -/.idea/workspace.xml -.DS_Store diff --git a/android/experimental/LOAndroid2/.idea/.name b/android/experimental/LOAndroid2/.idea/.name deleted file mode 100644 index 3300c569c980..000000000000 --- a/android/experimental/LOAndroid2/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -LOAndroid \ No newline at end of file diff --git a/android/experimental/LOAndroid2/.idea/compiler.xml b/android/experimental/LOAndroid2/.idea/compiler.xml deleted file mode 100644 index 217af471a9e6..000000000000 --- a/android/experimental/LOAndroid2/.idea/compiler.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml b/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml deleted file mode 100644 index e7bedf3377d4..000000000000 --- a/android/experimental/LOAndroid2/.idea/copyright/profiles_settings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid2/.idea/encodings.xml b/android/experimental/LOAndroid2/.idea/encodings.xml deleted file mode 100644 index e206d70d8595..000000000000 --- a/android/experimental/LOAndroid2/.idea/encodings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/android/experimental/LOAndroid2/.idea/gradle.xml b/android/experimental/LOAndroid2/.idea/gradle.xml deleted file mode 100644 index 736c7b5cffcc..000000000000 --- a/android/experimental/LOAndroid2/.idea/gradle.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/android/experimental/LOAndroid2/.idea/misc.xml b/android/experimental/LOAndroid2/.idea/misc.xml deleted file mode 100644 index 7f0862a388db..000000000000 --- a/android/experimental/LOAndroid2/.idea/misc.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - Abstraction issues - - - - - - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid2/.idea/modules.xml b/android/experimental/LOAndroid2/.idea/modules.xml deleted file mode 100644 index d5e166fb414b..000000000000 --- a/android/experimental/LOAndroid2/.idea/modules.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml b/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml deleted file mode 100644 index 922003b8433b..000000000000 --- a/android/experimental/LOAndroid2/.idea/scopes/scope_settings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid2/.idea/vcs.xml b/android/experimental/LOAndroid2/.idea/vcs.xml deleted file mode 100644 index def6a6a18457..000000000000 --- a/android/experimental/LOAndroid2/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/android/experimental/LOAndroid2/LOAndroid2.iml b/android/experimental/LOAndroid2/LOAndroid2.iml deleted file mode 100644 index 0bb6048ae08a..000000000000 --- a/android/experimental/LOAndroid2/LOAndroid2.iml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid2/app/.gitignore b/android/experimental/LOAndroid2/app/.gitignore deleted file mode 100644 index 796b96d1c402..000000000000 --- a/android/experimental/LOAndroid2/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/android/experimental/LOAndroid2/app/app.iml b/android/experimental/LOAndroid2/app/app.iml deleted file mode 100644 index 2fc60e01b0bf..000000000000 --- a/android/experimental/LOAndroid2/app/app.iml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid2/app/build.gradle b/android/experimental/LOAndroid2/app/build.gradle deleted file mode 100644 index 6053f9101f39..000000000000 --- a/android/experimental/LOAndroid2/app/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -apply plugin: 'android' - -android { - compileSdkVersion 19 - buildToolsVersion "19.1.0" - - defaultConfig { - minSdkVersion 15 - targetSdkVersion 19 - versionCode 1 - versionName "1.0" - } - buildTypes { - release { - runProguard false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' - } - } -} - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) -} diff --git a/android/experimental/LOAndroid2/app/proguard-rules.txt b/android/experimental/LOAndroid2/app/proguard-rules.txt deleted file mode 100644 index 0b0be289afc1..000000000000 --- a/android/experimental/LOAndroid2/app/proguard-rules.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /home/quikee/Programs/android-sdk-linux/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} \ No newline at end of file diff --git a/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml b/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml deleted file mode 100644 index aef4bb7b591d..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java deleted file mode 100644 index bf4f98b845da..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOEvent.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.libreoffice; - -import android.graphics.Rect; -import android.util.Log; - -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.ViewportMetrics; - -public class LOEvent { - - public static final int SIZE_CHANGED = 1; - public static final int TILE_SIZE = 2; - public static final int VIEWPORT = 3; - public static final int DRAW = 4; - - private ViewportMetrics mViewportMetrics; - - public int mType; - private String mTypeString; - - ViewportMetrics viewportMetrics; - - public LOEvent(int type, int width, int height, int widthPixels, int heightPixels, int tileWidth, int tileHeight) { - mType = type; - mTypeString = "Size Changed"; - } - - public LOEvent(int type, IntSize tileSize) { - mType = type; - mTypeString = "Tile size"; - } - - public LOEvent(int type, ViewportMetrics viewportMetrics) { - mType = type; - mTypeString = "Viewport"; - mViewportMetrics = viewportMetrics; - } - - public LOEvent(int type, Rect rect) { - mType = type; - mTypeString = "Draw"; - } - - public static LOEvent draw(Rect rect) { - return new LOEvent(DRAW, rect); - } - - public static LOEvent sizeChanged(int width, int height, int widthPixels, int heightPixels, int tileWidth, int tileHeight) { - return new LOEvent(SIZE_CHANGED, width, height, widthPixels, heightPixels, tileWidth, tileHeight); - } - - public static LOEvent tileSize(IntSize tileSize) { - return new LOEvent(TILE_SIZE, tileSize); - } - - public static LOEvent viewport(ViewportMetrics viewportMetrics) { - return new LOEvent(VIEWPORT, viewportMetrics); - } - - public String getTypeString() { - return mTypeString; - } - - public ViewportMetrics getViewport() { - return mViewportMetrics; - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java deleted file mode 100644 index 9dde7906d020..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitShell.java +++ /dev/null @@ -1,131 +0,0 @@ -package org.libreoffice; - - -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; - -import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient; -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.LayerView; - -import java.nio.ByteBuffer; - -public class LOKitShell { - private static final String LOGTAG = LOKitShell.class.getSimpleName(); - - public static int getDpi() { - return 96; - } - - public static int getScreenDepth() { - return 24; - } - - public static float computeRenderIntegrity() { - return 0.0f; - } - - public static ByteBuffer allocateDirectBuffer(int size) { - if (size <= 0) { - throw new IllegalArgumentException("Invalid size " + size); - } - - ByteBuffer directBuffer = ByteBuffer.allocateDirect(size); - //ByteBuffer directBuffer = nativeAllocateDirectBuffer(size); - if (directBuffer == null) { - throw new OutOfMemoryError("allocateDirectBuffer() returned null"); - } else if (!directBuffer.isDirect()) { - throw new AssertionError("allocateDirectBuffer() did not return a direct buffer"); - } - - return directBuffer; - } - - - public static void freeDirectBuffer(ByteBuffer buffer) { - if (buffer == null) { - return; - } - - if (!buffer.isDirect()) { - throw new IllegalArgumentException("buffer must be direct"); - } - //nativeFreeDirectBuffer(buffer); - return ; - } - - public static void bindWidgetTexture() { - } - - public static void sendEvent(LOEvent event) { - Log.i(LOGTAG, "Event: " + event.getTypeString()); - } - - public static void runGecko(String apkPath, String args, String url, boolean restoreSession) { - // run gecko -- it will spawn its own thread - // GeckoAppShell.nativeInit(); - - Log.i(LOGTAG, "post native init"); - - // Tell Gecko where the target byte buffer is for rendering - //GeckoAppShell.setSoftwareLayerClient(GeckoApp.mAppContext.getSoftwareLayerClient()); - - Log.i(LOGTAG, "setSoftwareLayerClient called"); - - // First argument is the .apk path - String combinedArgs = apkPath + " -greomni " + apkPath; - if (args != null) - combinedArgs += " " + args; - if (url != null) - combinedArgs += " -remote " + url; - if (restoreSession) - combinedArgs += " -restoresession"; - - DisplayMetrics metrics = new DisplayMetrics(); - LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - combinedArgs += " -width " + metrics.widthPixels + " -height " + metrics.heightPixels; - - LibreOfficeMainActivity.mAppContext.runOnUiThread(new Runnable() { - public void run() { - geckoLoaded(); - } - }); - - //LOKitShell.nativeRun(combinedArgs); - } - - // Called on the UI thread after Gecko loads. - private static void geckoLoaded() { - /*final LayerController layerController = LibreOfficeMainActivity.mAppContext.getLayerController(); - LayerView v = layerController.getView(); - mInputConnection = GeckoInputConnection.create(v); - v.setInputConnectionHandler(mInputConnection); - - layerController.setOnTouchListener(new View.OnTouchListener() { - public boolean onTouch(View view, MotionEvent event) { - if (event == null) - return true; - GeckoAppShell.sendEventToGecko(new GeckoEvent(event)); - return true; - } - }); - - layerController.notifyLayerClientOfGeometryChange();*/ - } - - public static void viewSizeChanged() { - } - - public static void scheduleComposite() { - } - - public static void schedulePauseComposition() { - } - - public static void scheduleResumeComposition() { - - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java deleted file mode 100644 index f486ad804512..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LOKitThread.java +++ /dev/null @@ -1,157 +0,0 @@ -package org.libreoffice; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.util.JsonWriter; - -import org.mozilla.gecko.gfx.ViewportMetrics; - -import java.io.IOException; -import java.io.StringWriter; -import java.nio.ByteBuffer; -import java.util.Random; -import java.util.concurrent.ConcurrentLinkedQueue; - -public class LOKitThread extends Thread { - private static final String LOGTAG = "GeckoThread"; - private static final int TILE_SIZE = 256; - - - public ConcurrentLinkedQueue gEvents = new ConcurrentLinkedQueue(); - private ViewportMetrics mViewportMetrics; - private Random rand = new Random(); - - LOKitThread() { - } - - private boolean draw() throws InterruptedException { - final LibreOfficeMainActivity application = LibreOfficeMainActivity.mAppContext; - - Bitmap originalBitmap = application.getLayerClient().getLayerController().getDrawable("dummy_page"); - - String metadata; - if (mViewportMetrics == null) { - metadata = createJson(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), originalBitmap.getWidth(), originalBitmap.getHeight(), 0, 0, 1.0); - } else { - metadata = createJson(mViewportMetrics); - } - - Rect bufferRect = application.getLayerClient().beginDrawing(originalBitmap.getWidth(), originalBitmap.getHeight(), 256, 256, metadata); - if (bufferRect == null) { - return false; - } - int x = 0; - int y = 0; - - for (Integer i = 1; i <= 9; i++) { - String imageName = "d" + i; - Bitmap bitmap = application.getLayerClient().getLayerController().getDrawable(imageName); - application.getLayerClient().addTile(bitmap, x, y); - x += TILE_SIZE; - if (x > originalBitmap.getWidth()) { - x = 0; - y += TILE_SIZE; - } - } - - application.getLayerClient().endDrawing(0, 0, originalBitmap.getWidth(), originalBitmap.getHeight()); - - application.runOnUiThread(new Runnable() { - @Override - public void run() { - application.getLayerClient().handleMessage("Viewport:UpdateLater", null); - } - }); - - return true; - } - - private String createJson(ViewportMetrics viewportMetrics) { - return createJson( - (int) viewportMetrics.getOrigin().x, - (int) viewportMetrics.getOrigin().y, - (int) viewportMetrics.getSize().width, - (int) viewportMetrics.getSize().height, - (int) viewportMetrics.getPageSize().width, - (int) viewportMetrics.getPageSize().height, - (int) viewportMetrics.getViewportOffset().x, - (int) viewportMetrics.getViewportOffset().y, - viewportMetrics.getZoomFactor()); - } - - private String createJson(int x, int y, int width, int height, int pageWidth, int pageHeight, int offsetX, int offsetY, double zoom) { - try { - StringWriter stringWriter = new StringWriter(); - JsonWriter writer = new JsonWriter(stringWriter); - writer.beginObject(); - writer.name("x").value(x); - writer.name("y").value(y); - writer.name("width").value(width); - writer.name("height").value(height); - writer.name("pageWidth").value(pageWidth); - writer.name("pageHeight").value(pageHeight); - writer.name("offsetX").value(offsetX); - writer.name("offsetY").value(offsetY); - writer.name("zoom").value(zoom); - writer.name("backgroundColor").value("rgb(255,255,255)"); - writer.endObject(); - writer.close(); - return stringWriter.toString(); - } catch (IOException ex) { - } - return null; - } - - private short convertTo16Bit(int color) { - int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3; - int c = ((r << 11) | (g << 5) | b); - // Swap endianness. - return (short) ((c >> 8) | ((c & 0xff) << 8)); - } - - private Bitmap convert(Bitmap bitmap, Bitmap.Config config) { - Bitmap convertedBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), config); - Canvas canvas = new Canvas(convertedBitmap); - Paint paint = new Paint(); - paint.setColor(Color.BLACK); - canvas.drawBitmap(bitmap, 0, 0, paint); - return convertedBitmap; - } - - - public void run() { - try { - boolean drawn = false; - while (true) { - - if (!gEvents.isEmpty()) { - processEvent(gEvents.poll()); - } else { - if (!drawn) { - drawn = draw(); - } - Thread.sleep(100L); - } - } - } catch (InterruptedException ex) { - } - } - - private void processEvent(LOEvent event) throws InterruptedException { - switch (event.mType) { - case LOEvent.VIEWPORT: - mViewportMetrics = event.getViewport(); - break; - case LOEvent.DRAW: - draw(); - break; - case LOEvent.SIZE_CHANGED: - break; - } - } - - -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java b/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java deleted file mode 100644 index 934464d2dea6..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/libreoffice/LibreOfficeMainActivity.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.libreoffice; - -import android.app.Activity; -import android.os.Bundle; -import android.os.SystemClock; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; - -import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.LayerView; - -public class LibreOfficeMainActivity extends Activity { - - private static final String LOGTAG = "LibreOfficeMainActivity"; - - private LinearLayout mMainLayout; - private RelativeLayout mGeckoLayout; - private static LayerController mLayerController; - private static GeckoSoftwareLayerClient mLayerClient; - private static LOKitThread sLOKitThread; - - public static LibreOfficeMainActivity mAppContext; - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.main, menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. - int id = item.getItemId(); - if (id == R.id.action_settings) { - return true; - } - return super.onOptionsItemSelected(item); - } - - public DisplayMetrics getDisplayMetrics() { - DisplayMetrics metrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(metrics); - return metrics; - } - - /** - * Called when the activity is first created. - */ - @Override - public void onCreate(Bundle savedInstanceState) { - mAppContext = this; - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - onCreate"); - - setContentView(R.layout.activity_main); - - // setup gecko layout - mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout); - mMainLayout = (LinearLayout) findViewById(R.id.main_layout); - - - if (mLayerController == null) { - mLayerController = new LayerController(this); - - Log.e(LOGTAG, "### Creating GeckoSoftwareLayerClient"); - mLayerClient = new GeckoSoftwareLayerClient(this); - Log.e(LOGTAG, "### Done creating GeckoSoftwareLayerClient"); - - mLayerController.setLayerClient(mLayerClient); - mGeckoLayout.addView(mLayerController.getView(), 0); - } - - mLayerController.notifyLayerClientOfGeometryChange(); - - sLOKitThread = new LOKitThread(); - sLOKitThread.start(); - - - Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - UI almost up"); - } - - public static GeckoSoftwareLayerClient getLayerClient() { - return mLayerClient; - } - - public static LayerController getLayerController() { - return mLayerController; - } -} \ No newline at end of file diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java deleted file mode 100644 index 670513f2cfb2..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/GeckoEventListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Sriram Ramasubramanian - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko; - -import org.json.JSONObject; - -public interface GeckoEventListener { - public void handleMessage(String event, JSONObject message); -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java deleted file mode 100644 index 2ffe11329f85..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/BufferedCairoImage.java +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Bitmap; - -import org.libreoffice.LOKitShell; - -import java.nio.ByteBuffer; - -//import org.mozilla.gecko.GeckoAppShell; - -/** - * A Cairo image that simply saves a buffer of pixel data. - */ -public class BufferedCairoImage extends CairoImage { - private ByteBuffer mBuffer; - private IntSize mSize; - private int mFormat; - private boolean mNeedToFreeBuffer = false; - - /** - * Creates a buffered Cairo image from a byte buffer. - */ - public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) { - mBuffer = inBuffer; - mSize = new IntSize(inWidth, inHeight); - mFormat = inFormat; - } - - /** - * Creates a buffered Cairo image from an Android bitmap. - */ - public BufferedCairoImage(Bitmap bitmap) { - mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig()); - mSize = new IntSize(bitmap.getWidth(), bitmap.getHeight()); - mNeedToFreeBuffer = true; - // XXX Why is this * 4? Shouldn't it depend on mFormat? - mBuffer = LOKitShell.allocateDirectBuffer(mSize.getArea() * 4); - - bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer()); - } - - protected void finalize() throws Throwable { - try { - if (mNeedToFreeBuffer && mBuffer != null) - LOKitShell.freeDirectBuffer(mBuffer); - mNeedToFreeBuffer = false; - mBuffer = null; - } finally { - super.finalize(); - } - } - - @Override - public ByteBuffer getBuffer() { - return mBuffer; - } - - @Override - public IntSize getSize() { - return mSize; - } - - @Override - public int getFormat() { - return mFormat; - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java deleted file mode 100644 index bd4eedcaf951..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoGLInfo.java +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import javax.microedition.khronos.opengles.GL10; - -/** - * Information needed to render Cairo bitmaps using OpenGL ES. - */ -public class CairoGLInfo { - public final int internalFormat; - public final int format; - public final int type; - - public CairoGLInfo(int cairoFormat) { - switch (cairoFormat) { - case CairoImage.FORMAT_ARGB32: - internalFormat = format = GL10.GL_RGBA; - type = GL10.GL_UNSIGNED_BYTE; - break; - case CairoImage.FORMAT_RGB24: - internalFormat = format = GL10.GL_RGB; - type = GL10.GL_UNSIGNED_BYTE; - break; - case CairoImage.FORMAT_RGB16_565: - internalFormat = format = GL10.GL_RGB; - type = GL10.GL_UNSIGNED_SHORT_5_6_5; - break; - case CairoImage.FORMAT_A8: - case CairoImage.FORMAT_A1: - throw new RuntimeException("Cairo FORMAT_A1 and FORMAT_A8 unsupported"); - default: - throw new RuntimeException("Unknown Cairo format"); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java deleted file mode 100644 index 06c389dd0524..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoImage.java +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import java.nio.ByteBuffer; - -/* - * A bitmap with pixel data in one of the formats that Cairo understands. - */ -public abstract class CairoImage { - public abstract ByteBuffer getBuffer(); - - public abstract IntSize getSize(); - public abstract int getFormat(); - - public static final int FORMAT_INVALID = -1; - public static final int FORMAT_ARGB32 = 0; - public static final int FORMAT_RGB24 = 1; - public static final int FORMAT_A8 = 2; - public static final int FORMAT_A1 = 3; - public static final int FORMAT_RGB16_565 = 4; -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java deleted file mode 100644 index 00bd896e1664..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CairoUtils.java +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.gfx.CairoImage; -import android.graphics.Bitmap; -import javax.microedition.khronos.opengles.GL10; - -/** - * Utility methods useful when displaying Cairo bitmaps using OpenGL ES. - */ -public class CairoUtils { - private CairoUtils() { /* Don't call me. */ } - - public static int bitsPerPixelForCairoFormat(int cairoFormat) { - switch (cairoFormat) { - case CairoImage.FORMAT_A1: return 1; - case CairoImage.FORMAT_A8: return 8; - case CairoImage.FORMAT_RGB16_565: return 16; - case CairoImage.FORMAT_RGB24: return 24; - case CairoImage.FORMAT_ARGB32: return 32; - default: - throw new RuntimeException("Unknown Cairo format"); - } - } - - public static int bitmapConfigToCairoFormat(Bitmap.Config config) { - if (config == null) - return CairoImage.FORMAT_ARGB32; /* Droid Pro fix. */ - - switch (config) { - case ALPHA_8: return CairoImage.FORMAT_A8; - case ARGB_4444: throw new RuntimeException("ARGB_444 unsupported"); - case ARGB_8888: return CairoImage.FORMAT_ARGB32; - case RGB_565: return CairoImage.FORMAT_RGB16_565; - default: throw new RuntimeException("Unknown Skia bitmap config"); - } - } - - public static Bitmap.Config cairoFormatTobitmapConfig(int format) { - switch (format) { - case CairoImage.FORMAT_A8: return Bitmap.Config.ALPHA_8; - case CairoImage.FORMAT_ARGB32: return Bitmap.Config.ARGB_8888; - case CairoImage.FORMAT_RGB16_565: return Bitmap.Config.RGB_565; - default: - throw new RuntimeException("Unknown CairoImage format"); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java deleted file mode 100644 index 392d7e8d8463..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/CheckerboardImage.java +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -import android.graphics.Color; -import java.nio.ByteBuffer; -import java.nio.ShortBuffer; -import java.util.Arrays; - -/** A Cairo image that displays a tinted checkerboard. */ -public class CheckerboardImage extends CairoImage { - // The width and height of the checkerboard tile. - private static final int SIZE = 16; - // The pixel format of the checkerboard tile. - private static final int FORMAT = CairoImage.FORMAT_RGB16_565; - // The color to mix in to tint the background color. - private static final int TINT_COLOR = Color.GRAY; - // The amount to mix in. - private static final float TINT_OPACITY = 0.4f; - - private ByteBuffer mBuffer; - private int mMainColor; - private boolean mShowChecks; - - /** Creates a new checkerboard image. */ - public CheckerboardImage() { - int bpp = CairoUtils.bitsPerPixelForCairoFormat(FORMAT); - mBuffer = LOKitShell.allocateDirectBuffer(SIZE * SIZE * bpp / 8); - update(true, Color.WHITE); - } - - /** Returns the current color of the checkerboard. */ - public int getColor() { - return mMainColor; - } - - /** Returns whether or not we are currently showing checks on the checkerboard. */ - public boolean getShowChecks() { - return mShowChecks; - } - - /** Updates the checkerboard image. If showChecks is true, then create a - checkerboard image that is tinted to the color. Otherwise just return a flat - image of the color. */ - public void update(boolean showChecks, int color) { - mMainColor = color; - mShowChecks = showChecks; - - short mainColor16 = convertTo16Bit(mMainColor); - - mBuffer.rewind(); - ShortBuffer shortBuffer = mBuffer.asShortBuffer(); - - if (!mShowChecks) { - short color16 = convertTo16Bit(mMainColor); - short[] fillBuffer = new short[SIZE]; - Arrays.fill(fillBuffer, color16); - - for (int i = 0; i < SIZE; i++) { - shortBuffer.put(fillBuffer); - } - - return; - } - - short tintColor16 = convertTo16Bit(tint(mMainColor)); - - short[] mainPattern = new short[SIZE / 2], tintPattern = new short[SIZE / 2]; - Arrays.fill(mainPattern, mainColor16); - Arrays.fill(tintPattern, tintColor16); - - // The checkerboard pattern looks like this: - // - // +---+---+ - // | N | T | N = normal - // +---+---+ T = tinted - // | T | N | - // +---+---+ - - for (int i = 0; i < SIZE / 2; i++) { - shortBuffer.put(mainPattern); - shortBuffer.put(tintPattern); - } - for (int i = SIZE / 2; i < SIZE; i++) { - shortBuffer.put(tintPattern); - shortBuffer.put(mainPattern); - } - } - - // Tints the given color appropriately and returns the tinted color. - private int tint(int color) { - float negTintOpacity = 1.0f - TINT_OPACITY; - float r = Color.red(color) * negTintOpacity + Color.red(TINT_COLOR) * TINT_OPACITY; - float g = Color.green(color) * negTintOpacity + Color.green(TINT_COLOR) * TINT_OPACITY; - float b = Color.blue(color) * negTintOpacity + Color.blue(TINT_COLOR) * TINT_OPACITY; - return Color.rgb(Math.round(r), Math.round(g), Math.round(b)); - } - - // Converts a 32-bit ARGB color to 16-bit R5G6B5, truncating values and discarding the alpha - // channel. - private short convertTo16Bit(int color) { - int r = Color.red(color) >> 3, g = Color.green(color) >> 2, b = Color.blue(color) >> 3; - int c = ((r << 11) | (g << 5) | b); - // Swap endianness. - return (short)((c >> 8) | ((c & 0xff) << 8)); - } - - @Override - protected void finalize() throws Throwable { - try { - if (mBuffer != null) { - LOKitShell.freeDirectBuffer(mBuffer); - } - } finally { - super.finalize(); - } - } - - @Override - public ByteBuffer getBuffer() { - return mBuffer; - } - - @Override - public IntSize getSize() { - return new IntSize(SIZE, SIZE); - } - - @Override - public int getFormat() { - return FORMAT; - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java deleted file mode 100644 index dc20077b0457..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FlexibleGLSurfaceView.java +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011-2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoApp; -import android.content.Context; -import android.graphics.PixelFormat; -import android.opengl.GLSurfaceView; -import android.util.AttributeSet; -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; - -import org.libreoffice.LibreOfficeMainActivity; - -public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { - private static final String LOGTAG = "GeckoFlexibleGLSurfaceView"; - - private GLSurfaceView.Renderer mRenderer; - private GLThread mGLThread; // Protected by this class's monitor. - private GLController mController; - private Listener mListener; - - public FlexibleGLSurfaceView(Context context) { - super(context); - init(); - } - - public FlexibleGLSurfaceView(Context context, AttributeSet attributeSet) { - super(context, attributeSet); - init(); - } - - public void init() { - SurfaceHolder holder = getHolder(); - holder.addCallback(this); - holder.setFormat(PixelFormat.RGB_565); - - mController = new GLController(this); - } - - public void setRenderer(GLSurfaceView.Renderer renderer) { - mRenderer = renderer; - } - - public GLSurfaceView.Renderer getRenderer() { - return mRenderer; - } - - public void setListener(Listener listener) { - mListener = listener; - } - - public synchronized void requestRender() { - if (mGLThread != null) { - mGLThread.renderFrame(); - } - if (mListener != null) { - mListener.renderRequested(); - } - } - - /** - * Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just - * like a GLSurfaceView. It is illegal to access the controller after this has been called. - */ - public synchronized void createGLThread() { - if (mGLThread != null) { - throw new FlexibleGLSurfaceViewException("createGLThread() called with a GL thread " + - "already in place!"); - } - - Log.e(LOGTAG, "### Creating GL thread!"); - mGLThread = new GLThread(mController); - mGLThread.start(); - notifyAll(); - } - - /** - * Destroys the Java GL thread. Returns a Thread that completes when the Java GL thread is - * fully shut down. - */ - public synchronized Thread destroyGLThread() { - // Wait for the GL thread to be started. - Log.e(LOGTAG, "### Waiting for GL thread to be created..."); - while (mGLThread == null) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - Log.e(LOGTAG, "### Destroying GL thread!"); - Thread glThread = mGLThread; - mGLThread.shutdown(); - mGLThread = null; - return glThread; - } - - public synchronized void recreateSurface() { - if (mGLThread == null) { - throw new FlexibleGLSurfaceViewException("recreateSurface() called with no GL " + - "thread active!"); - } - - mGLThread.recreateSurface(); - } - - public synchronized GLController getGLController() { - if (mGLThread != null) { - throw new FlexibleGLSurfaceViewException("getGLController() called with a GL thread " + - "active; shut down the GL thread first!"); - } - - return mController; - } - - public synchronized void surfaceChanged(SurfaceHolder holder, int format, int width, - int height) { - mController.sizeChanged(width, height); - if (mGLThread != null) { - mGLThread.surfaceChanged(width, height); - } - - if (mListener != null) { - mListener.surfaceChanged(width, height); - } - } - - public synchronized void surfaceCreated(SurfaceHolder holder) { - mController.surfaceCreated(); - if (mGLThread != null) { - mGLThread.surfaceCreated(); - } - } - - public synchronized void surfaceDestroyed(SurfaceHolder holder) { - mController.surfaceDestroyed(); - if (mGLThread != null) { - mGLThread.surfaceDestroyed(); - } - - if (mListener != null) { - mListener.compositionPauseRequested(); - } - } - - // Called from the compositor thread - public static GLController registerCxxCompositor() { - try { - Log.e(LOGTAG, "### registerCxxCompositor point A"); - System.out.println("register layer comp"); - Log.e(LOGTAG, "### registerCxxCompositor point B"); - FlexibleGLSurfaceView flexView = (FlexibleGLSurfaceView) /*GeckoApp*/LibreOfficeMainActivity.mAppContext.getLayerController().getView(); - Log.e(LOGTAG, "### registerCxxCompositor point C: " + flexView); - try { - flexView.destroyGLThread().join(); - } catch (InterruptedException e) {} - Log.e(LOGTAG, "### registerCxxCompositor point D: " + flexView.getGLController()); - return flexView.getGLController(); - } catch (Exception e) { - Log.e(LOGTAG, "### Exception! " + e); - return null; - } - } - - public interface Listener { - void renderRequested(); - void compositionPauseRequested(); - void compositionResumeRequested(); - void surfaceChanged(int width, int height); - } - - public static class FlexibleGLSurfaceViewException extends RuntimeException { - public static final long serialVersionUID = 1L; - - FlexibleGLSurfaceViewException(String e) { - super(e); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java deleted file mode 100644 index 5fb73ec18df9..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/FloatSize.java +++ /dev/null @@ -1,99 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.json.JSONException; -import org.json.JSONObject; -import org.mozilla.gecko.util.FloatUtils; - -public class FloatSize { - public final float width, height; - - public FloatSize(FloatSize size) { - width = size.width; - height = size.height; - } - - public FloatSize(IntSize size) { - width = size.width; - height = size.height; - } - - public FloatSize(float aWidth, float aHeight) { - width = aWidth; - height = aHeight; - } - - public FloatSize(JSONObject json) { - try { - width = (float) json.getDouble("width"); - height = (float) json.getDouble("height"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - @Override - public String toString() { - return "(" + width + "," + height + ")"; - } - - public boolean isPositive() { - return (width > 0 && height > 0); - } - - public boolean fuzzyEquals(FloatSize size) { - return (FloatUtils.fuzzyEquals(size.width, width) && - FloatUtils.fuzzyEquals(size.height, height)); - } - - public FloatSize scale(float factor) { - return new FloatSize(width * factor, height * factor); - } - - /* - * Returns the size that represents a linear transition between this size and `to` at time `t`, - * which is on the scale [0, 1). - */ - public FloatSize interpolate(FloatSize to, float t) { - return new FloatSize(FloatUtils.interpolate(width, to.width, t), - FloatUtils.interpolate(height, to.height, t)); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java deleted file mode 100644 index e8f201228666..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLController.java +++ /dev/null @@ -1,279 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011-2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.util.Log; -import android.view.SurfaceHolder; -import android.view.SurfaceView; -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGL11; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; -import javax.microedition.khronos.opengles.GL; -import javax.microedition.khronos.opengles.GL10; - -public class GLController { - private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - private static final String LOGTAG = "GeckoGLController"; - - private FlexibleGLSurfaceView mView; - private int mGLVersion; - private boolean mSurfaceValid; - private int mWidth, mHeight; - - private EGL10 mEGL; - private EGLDisplay mEGLDisplay; - private EGLConfig mEGLConfig; - private EGLContext mEGLContext; - private EGLSurface mEGLSurface; - - private GL mGL; - - private static final int LOCAL_EGL_OPENGL_ES2_BIT = 4; - - private static final int[] CONFIG_SPEC = { - EGL10.EGL_RED_SIZE, 5, - EGL10.EGL_GREEN_SIZE, 6, - EGL10.EGL_BLUE_SIZE, 5, - EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT, - EGL10.EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT, - EGL10.EGL_NONE - }; - - public GLController(FlexibleGLSurfaceView view) { - mView = view; - mGLVersion = 2; - mSurfaceValid = false; - } - - public void setGLVersion(int version) { - mGLVersion = version; - } - - /** You must call this on the same thread you intend to use OpenGL on. */ - public void initGLContext() { - initEGLContext(); - createEGLSurface(); - } - - public void disposeGLContext() { - if (!mEGL.eglMakeCurrent(mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, - EGL10.EGL_NO_CONTEXT)) { - throw new GLControllerException("EGL context could not be released!"); - } - - if (mEGLSurface != null) { - if (!mEGL.eglDestroySurface(mEGLDisplay, mEGLSurface)) { - throw new GLControllerException("EGL surface could not be destroyed!"); - } - - mEGLSurface = null; - } - - if (mEGLContext == null) { - if (!mEGL.eglDestroyContext(mEGLDisplay, mEGLContext)) { - throw new GLControllerException("EGL context could not be destroyed!"); - } - - mGL = null; - mEGLDisplay = null; - mEGLConfig = null; - mEGLContext = null; - } - } - - public GL getGL() { return mEGLContext.getGL(); } - public EGLDisplay getEGLDisplay() { return mEGLDisplay; } - public EGLConfig getEGLConfig() { return mEGLConfig; } - public EGLContext getEGLContext() { return mEGLContext; } - public EGLSurface getEGLSurface() { return mEGLSurface; } - public FlexibleGLSurfaceView getView() { return mView; } - - public boolean hasSurface() { - return mEGLSurface != null; - } - - public boolean swapBuffers() { - return mEGL.eglSwapBuffers(mEGLDisplay, mEGLSurface); - } - - public boolean checkForLostContext() { - if (mEGL.eglGetError() != EGL11.EGL_CONTEXT_LOST) { - return false; - } - - mEGLDisplay = null; - mEGLConfig = null; - mEGLContext = null; - mEGLSurface = null; - mGL = null; - return true; - } - - public synchronized void waitForValidSurface() { - while (!mSurfaceValid) { - try { - wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - } - - public synchronized int getWidth() { - return mWidth; - } - - public synchronized int getHeight() { - return mHeight; - } - - synchronized void surfaceCreated() { - mSurfaceValid = true; - notifyAll(); - } - - synchronized void surfaceDestroyed() { - mSurfaceValid = false; - notifyAll(); - } - - synchronized void sizeChanged(int newWidth, int newHeight) { - mWidth = newWidth; - mHeight = newHeight; - } - - private void initEGL() { - mEGL = (EGL10)EGLContext.getEGL(); - - mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) { - throw new GLControllerException("eglGetDisplay() failed"); - } - - int[] version = new int[2]; - if (!mEGL.eglInitialize(mEGLDisplay, version)) { - throw new GLControllerException("eglInitialize() failed"); - } - - mEGLConfig = chooseConfig(); - } - - private void initEGLContext() { - initEGL(); - - int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, mGLVersion, EGL10.EGL_NONE }; - mEGLContext = mEGL.eglCreateContext(mEGLDisplay, mEGLConfig, EGL10.EGL_NO_CONTEXT, - attribList); - if (mEGLContext == null || mEGLContext == EGL10.EGL_NO_CONTEXT) { - throw new GLControllerException("createContext() failed"); - } - } - - private EGLConfig chooseConfig() { - int[] numConfigs = new int[1]; - if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, null, 0, numConfigs) || - numConfigs[0] <= 0) { - throw new GLControllerException("No available EGL configurations"); - } - - EGLConfig[] configs = new EGLConfig[numConfigs[0]]; - if (!mEGL.eglChooseConfig(mEGLDisplay, CONFIG_SPEC, configs, numConfigs[0], numConfigs)) { - throw new GLControllerException("No EGL configuration for that specification"); - } - - // Select the first 565 RGB configuration. - int[] red = new int[1], green = new int[1], blue = new int[1]; - for (EGLConfig config : configs) { - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_RED_SIZE, red); - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_GREEN_SIZE, green); - mEGL.eglGetConfigAttrib(mEGLDisplay, config, EGL10.EGL_BLUE_SIZE, blue); - if (red[0] == 5 && green[0] == 6 && blue[0] == 5) { - return config; - } - } - - throw new GLControllerException("No suitable EGL configuration found"); - } - - private void createEGLSurface() { - SurfaceHolder surfaceHolder = mView.getHolder(); - mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); - if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) { - throw new GLControllerException("EGL window surface could not be created!"); - } - - if (!mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) { - throw new GLControllerException("EGL surface could not be made into the current " + - "surface!"); - } - - mGL = mEGLContext.getGL(); - - if (mView.getRenderer() != null) { - mView.getRenderer().onSurfaceCreated((GL10)mGL, mEGLConfig); - mView.getRenderer().onSurfaceChanged((GL10)mGL, mView.getWidth(), mView.getHeight()); - } - } - - // Provides an EGLSurface without assuming ownership of this surface. - private EGLSurface provideEGLSurface() { - if (mEGL == null) { - initEGL(); - } - - SurfaceHolder surfaceHolder = mView.getHolder(); - mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null); - if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) { - throw new GLControllerException("EGL window surface could not be created!"); - } - - return mEGLSurface; - } - - public static class GLControllerException extends RuntimeException { - public static final long serialVersionUID = 1L; - - GLControllerException(String e) { - super(e); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java deleted file mode 100644 index 4f788f64ebcb..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GLThread.java +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011-2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.opengl.GLSurfaceView; -import android.view.SurfaceHolder; -import javax.microedition.khronos.opengles.GL10; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; - -// A GL thread managed by Java. It is not necessary to use this class to use the -// FlexibleGLSurfaceView, but it can be helpful, especially if the GL rendering is to be done -// entirely in Java. -class GLThread extends Thread { - private LinkedBlockingQueue mQueue; - private GLController mController; - private boolean mRenderQueued; - - public GLThread(GLController controller) { - mQueue = new LinkedBlockingQueue(); - mController = controller; - } - - @Override - public void run() { - while (true) { - Runnable runnable; - try { - runnable = mQueue.take(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - runnable.run(); - if (runnable instanceof ShutdownMessage) { - break; - } - } - } - - public void recreateSurface() { - mQueue.add(new RecreateSurfaceMessage()); - } - - public void renderFrame() { - // Make sure there's only one render event in the queue at a time. - synchronized (this) { - if (!mRenderQueued) { - mQueue.add(new RenderFrameMessage()); - mRenderQueued = true; - } - } - } - - public void shutdown() { - mQueue.add(new ShutdownMessage()); - } - - public void surfaceChanged(int width, int height) { - mQueue.add(new SizeChangedMessage(width, height)); - } - - public void surfaceCreated() { - mQueue.add(new SurfaceCreatedMessage()); - } - - public void surfaceDestroyed() { - mQueue.add(new SurfaceDestroyedMessage()); - } - - private void doRecreateSurface() { - mController.disposeGLContext(); - mController.initGLContext(); - } - - private GLSurfaceView.Renderer getRenderer() { - return mController.getView().getRenderer(); - } - - private class RecreateSurfaceMessage implements Runnable { - public void run() { - doRecreateSurface(); - } - } - - private class RenderFrameMessage implements Runnable { - public void run() { - synchronized (GLThread.this) { - mRenderQueued = false; - } - - // Bail out if the surface was lost. - if (mController.getEGLSurface() == null) { - return; - } - - GLSurfaceView.Renderer renderer = getRenderer(); - if (renderer != null) { - renderer.onDrawFrame((GL10)mController.getGL()); - } - - mController.swapBuffers(); - //if (!mController.swapBuffers() && mController.checkForLostContext()) { - // doRecreateSurface(); - //} - } - } - - private class ShutdownMessage implements Runnable { - public void run() { - mController.disposeGLContext(); - mController = null; - } - } - - private class SizeChangedMessage implements Runnable { - private int mWidth, mHeight; - - public SizeChangedMessage(int width, int height) { - mWidth = width; - mHeight = height; - } - - public void run() { - GLSurfaceView.Renderer renderer = getRenderer(); - if (renderer != null) { - renderer.onSurfaceChanged((GL10)mController.getGL(), mWidth, mHeight); - } - } - } - - private class SurfaceCreatedMessage implements Runnable { - public void run() { - if (!mController.hasSurface()) { - mController.initGLContext(); - } - } - } - - private class SurfaceDestroyedMessage implements Runnable { - public void run() { - mController.disposeGLContext(); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java deleted file mode 100644 index 134c40628d0b..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ /dev/null @@ -1,398 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Color; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import android.os.SystemClock; -import android.util.DisplayMetrics; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; -import org.libreoffice.LOEvent; -import org.libreoffice.LOKitShell; -import org.libreoffice.LibreOfficeMainActivity; -import org.mozilla.gecko.GeckoEventListener; -import org.mozilla.gecko.util.FloatUtils; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -//import org.mozilla.gecko.GeckoApp; -//import org.mozilla.gecko.GeckoAppShell; -//import org.mozilla.gecko.GeckoEvent; - -public abstract class GeckoLayerClient extends LayerClient implements GeckoEventListener { - public static final int LAYER_CLIENT_TYPE_NONE = 0; - public static final int LAYER_CLIENT_TYPE_SOFTWARE = 1; - public static final int LAYER_CLIENT_TYPE_GL = 2; - - private static final String LOGTAG = "GeckoLayerClient"; - private static final long MIN_VIEWPORT_CHANGE_DELAY = 25L; - private static Pattern sColorPattern; - protected IntSize mScreenSize; - protected Layer mTileLayer; - /* The viewport that Gecko is currently displaying. */ - protected ViewportMetrics mGeckoViewport; - /* The viewport that Gecko will display when drawing is finished */ - protected ViewportMetrics mNewGeckoViewport; - private long mLastViewportChangeTime; - private boolean mPendingViewportAdjust; - private boolean mViewportSizeChanged; - - // mUpdateViewportOnEndDraw is used to indicate that we received a - // viewport update notification while drawing. therefore, when the - // draw finishes, we need to update the entire viewport rather than - // just the page size. this boolean should always be accessed from - // inside a transaction, so no synchronization is needed. - private boolean mUpdateViewportOnEndDraw; - private String mLastCheckerboardColor; - /* Used by robocop for testing purposes */ - private DrawListener mDrawListener; - - public GeckoLayerClient(Context context) { - mScreenSize = new IntSize(0, 0); - } - - // Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color - // cannot be parsed, returns white. - private static int parseColorFromGecko(String string) { - if (sColorPattern == null) { - sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)"); - } - - Matcher matcher = sColorPattern.matcher(string); - if (!matcher.matches()) { - return Color.WHITE; - } - - int r = Integer.parseInt(matcher.group(1)); - int g = Integer.parseInt(matcher.group(2)); - int b = Integer.parseInt(matcher.group(3)); - return Color.rgb(r, g, b); - } - - protected abstract boolean setupLayer(); - - protected abstract boolean shouldDrawProceed(int tileWidth, int tileHeight); - - protected abstract void updateLayerAfterDraw(Rect updatedRect); - - protected abstract IntSize getBufferSize(); - - protected abstract IntSize getTileSize(); - - protected abstract void tileLayerUpdated(); - - public abstract Bitmap getBitmap(); - - public abstract int getType(); - - /** - * Attaches the root layer to the layer controller so that Gecko appears. - */ - @Override - public void setLayerController(LayerController layerController) { - super.setLayerController(layerController); - - layerController.setRoot(mTileLayer); - if (mGeckoViewport != null) { - layerController.setViewportMetrics(mGeckoViewport); - } - - sendResizeEventIfNecessary(); - } - - public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) { - - Log.e(LOGTAG, "### beginDrawing " + width + " " + height + " " + tileWidth + " " + tileHeight); - - if (setupLayer()) { - Log.e(LOGTAG, "### Cancelling due to layer setup"); - return null; - } - - if (!shouldDrawProceed(tileWidth, tileHeight)) { - Log.e(LOGTAG, "### Cancelling draw due to shouldDrawProceed()"); - return null; - } - - LayerController controller = getLayerController(); - - try { - JSONObject viewportObject = new JSONObject(metadata); - mNewGeckoViewport = new ViewportMetrics(viewportObject); - - Log.e(LOGTAG, "### beginDrawing new Gecko viewport " + mNewGeckoViewport); - - // Update the background color, if it's present. - String backgroundColorString = viewportObject.optString("backgroundColor"); - if (backgroundColorString != null && !backgroundColorString.equals(mLastCheckerboardColor)) { - mLastCheckerboardColor = backgroundColorString; - controller.setCheckerboardColor(parseColorFromGecko(backgroundColorString)); - } - } catch (JSONException e) { - Log.e(LOGTAG, "Aborting draw, bad viewport description: " + metadata); - return null; - } - - // Make sure we don't spend time painting areas we aren't interested in. - // Only do this if the Gecko viewport isn't going to override our viewport. - Rect bufferRect = new Rect(0, 0, width, height); - - if (!mUpdateViewportOnEndDraw) { - // First, find out our ideal displayport. We do this by taking the - // clamped viewport origin and taking away the optimum viewport offset. - // This would be what we would send to Gecko if adjustViewport were - // called now. - ViewportMetrics currentMetrics = controller.getViewportMetrics(); - PointF currentBestOrigin = RectUtils.getOrigin(currentMetrics.getClampedViewport()); - PointF viewportOffset = currentMetrics.getOptimumViewportOffset(new IntSize(width, height)); - currentBestOrigin.offset(-viewportOffset.x, -viewportOffset.y); - - Rect currentRect = RectUtils.round(new RectF(currentBestOrigin.x, currentBestOrigin.y, - currentBestOrigin.x + width, currentBestOrigin.y + height)); - - // Second, store Gecko's displayport. - PointF currentOrigin = mNewGeckoViewport.getDisplayportOrigin(); - bufferRect = RectUtils.round(new RectF(currentOrigin.x, currentOrigin.y, - currentOrigin.x + width, currentOrigin.y + height)); - - - // Take the intersection of the two as the area we're interested in rendering. - - if (!bufferRect.intersect(currentRect)) { - // If there's no intersection, we have no need to render anything, - // but make sure to update the viewport size. - beginTransaction(mTileLayer); - try { - updateViewport(true); - } finally { - endTransaction(mTileLayer); - } - return null; - } - bufferRect.offset(Math.round(-currentOrigin.x), Math.round(-currentOrigin.y)); - } - - beginTransaction(mTileLayer); - return bufferRect; - } - - /* - * TODO: Would be cleaner if this took an android.graphics.Rect instead, but that would require - * a little more JNI magic. - */ - public void endDrawing(int x, int y, int width, int height) { - synchronized (getLayerController()) { - try { - updateViewport(!mUpdateViewportOnEndDraw); - mUpdateViewportOnEndDraw = false; - - Rect rect = new Rect(x, y, x + width, y + height); - updateLayerAfterDraw(rect); - } finally { - endTransaction(mTileLayer); - } - } - Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - endDrawing"); - - /* Used by robocop for testing purposes */ - if (mDrawListener != null) { - mDrawListener.drawFinished(x, y, width, height); - } - } - - protected void updateViewport(boolean onlyUpdatePageSize) { - // save and restore the viewport size stored in java; never let the - // JS-side viewport dimensions override the java-side ones because - // java is the One True Source of this information, and allowing JS - // to override can lead to race conditions where this data gets clobbered. - FloatSize viewportSize = getLayerController().getViewportSize(); - mGeckoViewport = mNewGeckoViewport; - mGeckoViewport.setSize(viewportSize); - - LayerController controller = getLayerController(); - PointF displayportOrigin = mGeckoViewport.getDisplayportOrigin(); - mTileLayer.setOrigin(PointUtils.round(displayportOrigin)); - mTileLayer.setResolution(mGeckoViewport.getZoomFactor()); - - this.tileLayerUpdated(); - Log.e(LOGTAG, "### updateViewport onlyUpdatePageSize=" + onlyUpdatePageSize + " getTileViewport " + mGeckoViewport); - - if (onlyUpdatePageSize) { - // Don't adjust page size when zooming unless zoom levels are - // approximately equal. - if (FloatUtils.fuzzyEquals(controller.getZoomFactor(), mGeckoViewport.getZoomFactor())) { - controller.setPageSize(mGeckoViewport.getPageSize()); - } - } else { - controller.setViewportMetrics(mGeckoViewport); - controller.abortPanZoomAnimation(); - } - } - - /* Informs Gecko that the screen size has changed. */ - protected void sendResizeEventIfNecessary(boolean force) { - Log.e(LOGTAG, "### sendResizeEventIfNecessary " + force); - - DisplayMetrics metrics = new DisplayMetrics(); - LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - // Return immediately if the screen size hasn't changed or the viewport - // size is zero (which indicates that the rendering surface hasn't been - // allocated yet). - boolean screenSizeChanged = (metrics.widthPixels != mScreenSize.width || metrics.heightPixels != mScreenSize.height); - boolean viewportSizeValid = (getLayerController() != null && getLayerController().getViewportSize().isPositive()); - - if (!(force || (screenSizeChanged && viewportSizeValid))) { - return; - } - - mScreenSize = new IntSize(metrics.widthPixels, metrics.heightPixels); - IntSize bufferSize = getBufferSize(), tileSize = getTileSize(); - - Log.e(LOGTAG, "### Screen-size changed to " + mScreenSize); - - LOEvent event = LOEvent.sizeChanged(bufferSize.width, bufferSize.height, - metrics.widthPixels, metrics.heightPixels, - tileSize.width, tileSize.height); - LOKitShell.sendEvent(event); - } - - @Override - public void render() { - adjustViewportWithThrottling(); - } - - private void adjustViewportWithThrottling() { - if (!getLayerController().getRedrawHint()) - return; - - if (mPendingViewportAdjust) - return; - - long timeDelta = System.currentTimeMillis() - mLastViewportChangeTime; - if (timeDelta < MIN_VIEWPORT_CHANGE_DELAY) { - getLayerController().getView().postDelayed( - new Runnable() { - public void run() { - mPendingViewportAdjust = false; - adjustViewport(); - } - }, MIN_VIEWPORT_CHANGE_DELAY - timeDelta - ); - mPendingViewportAdjust = true; - return; - } - - adjustViewport(); - } - - @Override - public void viewportSizeChanged() { - mViewportSizeChanged = true; - } - - private void adjustViewport() { - ViewportMetrics viewportMetrics = new ViewportMetrics(getLayerController().getViewportMetrics()); - - PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(getBufferSize()); - viewportMetrics.setViewportOffset(viewportOffset); - viewportMetrics.setViewport(viewportMetrics.getClampedViewport()); - - LOKitShell.sendEvent(LOEvent.viewport(viewportMetrics)); - if (mViewportSizeChanged) { - mViewportSizeChanged = false; - LOKitShell.viewSizeChanged(); - } - - mLastViewportChangeTime = System.currentTimeMillis(); - } - - public void handleMessage(String event, JSONObject message) { - if ("Viewport:UpdateAndDraw".equals(event)) { - Log.e(LOGTAG, "### Java side Viewport:UpdateAndDraw()!"); - mUpdateViewportOnEndDraw = true; - - // Redraw everything. - IntSize bufferSize = getBufferSize(); - Rect rect = new Rect(0, 0, bufferSize.width, bufferSize.height); - LOKitShell.sendEvent(LOEvent.draw(rect)); - } else if ("Viewport:UpdateLater".equals(event)) { - Log.e(LOGTAG, "### Java side Viewport:UpdateLater()!"); - mUpdateViewportOnEndDraw = true; - } - } - - @Override - public void geometryChanged() { - sendResizeEventIfNecessary(); - render(); - } - - public ViewportMetrics getGeckoViewportMetrics() { - if (mGeckoViewport != null) - return new ViewportMetrics(mGeckoViewport); - return null; - } - - private void sendResizeEventIfNecessary() { - sendResizeEventIfNecessary(false); - } - - /** - * Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. - */ - public void setDrawListener(DrawListener listener) { - mDrawListener = listener; - } - - /** - * Used by robocop for testing purposes. Not for production use! This is used via reflection by robocop. - */ - public interface DrawListener { - public void drawFinished(int x, int y, int width, int height); - } -} \ No newline at end of file diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java deleted file mode 100644 index 9269f967f1d2..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/GeckoSoftwareLayerClient.java +++ /dev/null @@ -1,242 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.LayerClient; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.LayerRenderer; -import org.mozilla.gecko.gfx.MultiTileLayer; -import org.mozilla.gecko.gfx.PointUtils; -import org.mozilla.gecko.gfx.WidgetTileLayer; -//import org.mozilla.gecko.GeckoAppShell; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.util.Log; -import java.nio.ByteBuffer; - -/** - * Transfers a software-rendered Gecko to an ImageLayer so that it can be rendered by our - * compositor. - * - * TODO: Throttle down Gecko's priority when we pan and zoom. - */ -public class GeckoSoftwareLayerClient extends GeckoLayerClient { - private static final String LOGTAG = "GeckoSoftwareLayerClient"; - - private int mFormat; - private IntSize mViewportSize; - private IntSize mBufferSize; - private static final IntSize TILE_SIZE = new IntSize(256, 256); - - public GeckoSoftwareLayerClient(Context context) { - super(context); - mBufferSize = new IntSize(0,0); - mFormat = CairoImage.FORMAT_ARGB32; - - - } - - /*protected void finalize() throws Throwable { - try { - if (mBuffer != null) - LOKitShell.freeDirectBuffer(mBuffer); - mBuffer = null; - } finally { - super.finalize(); - } - }*/ - - public void setLayerController(LayerController layerController) { - super.setLayerController(layerController); - - layerController.setRoot(mTileLayer); - if (mGeckoViewport != null) { - layerController.setViewportMetrics(mGeckoViewport); - } - - sendResizeEventIfNecessary(false); - } - - @Override - protected boolean setupLayer() { - if (mTileLayer != null) - return false; - - Log.i(LOGTAG, "Creating MultiTileLayer"); - mTileLayer = new MultiTileLayer(TILE_SIZE); - - getLayerController().setRoot(mTileLayer); - - // Force a resize event to be sent because the results of this - // are different depending on what tile system we're using - sendResizeEventIfNecessary(true); - - return true; - } - - @Override - protected boolean shouldDrawProceed(int tileWidth, int tileHeight) { - // Make sure the tile-size matches. If it doesn't, we could crash trying - // to access invalid memory. - if (tileWidth != TILE_SIZE.width || tileHeight != TILE_SIZE.height) { - Log.e(LOGTAG, "Aborting draw, incorrect tile size of " + tileWidth + "x" + tileHeight); - return false; - } - return true; - } - - @Override - public Rect beginDrawing(int width, int height, int tileWidth, int tileHeight, String metadata) { - Rect bufferRect = super.beginDrawing(width, height, tileWidth, tileHeight, metadata); - - if (bufferRect == null) { - return bufferRect; - } - - // If the window size has changed, reallocate the buffer to match. - if (mBufferSize.width != width || mBufferSize.height != height) { - mBufferSize = new IntSize(width, height); - } - - return bufferRect; - } - - @Override - protected void updateLayerAfterDraw(Rect updatedRect) { - if (mTileLayer instanceof MultiTileLayer) { - ((MultiTileLayer)mTileLayer).invalidate(updatedRect); - } - } - - /*private void copyPixelsFromMultiTileLayer(Bitmap target) { - Canvas c = new Canvas(target); - ByteBuffer tileBuffer = mBuffer.slice(); - int bpp = CairoUtils.bitsPerPixelForCairoFormat(mFormat) / 8; - - for (int y = 0; y < mBufferSize.height; y += TILE_SIZE.height) { - for (int x = 0; x < mBufferSize.width; x += TILE_SIZE.width) { - // Calculate tile size - IntSize tileSize = new IntSize(Math.min(mBufferSize.width - x, TILE_SIZE.width), - Math.min(mBufferSize.height - y, TILE_SIZE.height)); - - // Create a Bitmap from this tile - Bitmap tile = Bitmap.createBitmap(tileSize.width, tileSize.height, - CairoUtils.cairoFormatTobitmapConfig(mFormat)); - tile.copyPixelsFromBuffer(tileBuffer.asIntBuffer()); - - // Copy the tile to the master Bitmap and recycle it - c.drawBitmap(tile, x, y, null); - tile.recycle(); - - // Progress the buffer to the next tile - tileBuffer.position(tileSize.getArea() * bpp); - tileBuffer = tileBuffer.slice(); - } - } - }*/ - - @Override - protected void tileLayerUpdated() { - /* No-op. */ - } - - @Override - public Bitmap getBitmap() { - if (mTileLayer == null) - return null; - - // Begin a tile transaction, otherwise the buffer can be destroyed while - // we're reading from it. - /*beginTransaction(mTileLayer); - try { - if (mBuffer == null || mBufferSize.width <= 0 || mBufferSize.height <= 0) - return null; - try { - Bitmap b = null; - - if (mTileLayer instanceof MultiTileLayer) { - b = Bitmap.createBitmap(mBufferSize.width, mBufferSize.height,CairoUtils.cairoFormatTobitmapConfig(mFormat)); - copyPixelsFromMultiTileLayer(b); - } else { - Log.w(LOGTAG, "getBitmap() called on a layer (" + mTileLayer + ") we don't know how to get a bitmap from"); - } - - return b; - } catch (OutOfMemoryError oom) { - Log.w(LOGTAG, "Unable to create bitmap", oom); - return null; - } - } finally { - endTransaction(mTileLayer); - }*/ - - return null; - } - - @Override - public int getType() { - return LAYER_CLIENT_TYPE_SOFTWARE; - } - - @Override - protected IntSize getBufferSize() { - return new IntSize( - ((mScreenSize.width + LayerController.MIN_BUFFER.width - 1) / TILE_SIZE.width + 1) * TILE_SIZE.width, - ((mScreenSize.height + LayerController.MIN_BUFFER.height - 1) / TILE_SIZE.height + 1) * TILE_SIZE.height); - } - - @Override - protected IntSize getTileSize() { - return TILE_SIZE; - } - - public void addTile(Bitmap bitmap, int x, int y) { - if (mTileLayer instanceof MultiTileLayer) { - ((MultiTileLayer)mTileLayer).addTile(bitmap, x, y); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java deleted file mode 100644 index 6fef53fb0535..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/InputConnectionHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mozilla.gecko.gfx; - -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.KeyEvent; - -public interface InputConnectionHandler -{ - InputConnection onCreateInputConnection(EditorInfo outAttrs); - boolean onKeyPreIme(int keyCode, KeyEvent event); - boolean onKeyDown(int keyCode, KeyEvent event); - boolean onKeyLongPress(int keyCode, KeyEvent event); - boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event); - boolean onKeyUp(int keyCode, KeyEvent event); -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java deleted file mode 100644 index ee43b1bf557b..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/IntSize.java +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.gfx.FloatSize; -import org.json.JSONException; -import org.json.JSONObject; -import java.lang.Math; - -public class IntSize { - public final int width, height; - - public IntSize(IntSize size) { width = size.width; height = size.height; } - public IntSize(int inWidth, int inHeight) { width = inWidth; height = inHeight; } - - public IntSize(FloatSize size) { - width = Math.round(size.width); - height = Math.round(size.height); - } - - public IntSize(JSONObject json) { - try { - width = json.getInt("width"); - height = json.getInt("height"); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - public int getArea() { - return width * height; - } - - public boolean equals(IntSize size) { - return ((size.width == width) && (size.height == height)); - } - - public boolean isPositive() { - return (width > 0 && height > 0); - } - - @Override - public String toString() { return "(" + width + "," + height + ")"; } - - public IntSize scale(float factor) { - return new IntSize(Math.round(width * factor), - Math.round(height * factor)); - } - - /* Returns the power of two that is greater than or equal to value */ - public static int nextPowerOfTwo(int value) { - // code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html - if (0 == value--) { - return 1; - } - value = (value >> 1) | value; - value = (value >> 2) | value; - value = (value >> 4) | value; - value = (value >> 8) | value; - value = (value >> 16) | value; - return value + 1; - } - - public IntSize nextPowerOfTwo() { - return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height)); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java deleted file mode 100644 index 40786532a303..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/Layer.java +++ /dev/null @@ -1,242 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Point; -import android.graphics.RectF; -import android.graphics.Region; - -import org.mozilla.gecko.util.FloatUtils; - -import java.nio.FloatBuffer; -import java.util.concurrent.locks.ReentrantLock; - -public abstract class Layer { - private final ReentrantLock mTransactionLock; - protected Point mOrigin; - protected float mResolution; - private boolean mInTransaction; - private Point mNewOrigin; - private float mNewResolution; - private LayerView mView; - - public Layer() { - mTransactionLock = new ReentrantLock(); - mOrigin = new Point(0, 0); - mResolution = 1.0f; - } - - /** - * Updates the layer. This returns false if there is still work to be done - * after this update. - */ - public final boolean update(RenderContext context) { - if (mTransactionLock.isHeldByCurrentThread()) { - throw new RuntimeException("draw() called while transaction lock held by this " + - "thread?!"); - } - - if (mTransactionLock.tryLock()) { - try { - return performUpdates(context); - } finally { - mTransactionLock.unlock(); - } - } - - return false; - } - - /** - * Subclasses override this function to draw the layer. - */ - public abstract void draw(RenderContext context); - - /** - * Subclasses override this function to provide access to the size of the layer. - */ - public abstract IntSize getSize(); - - /** - * Given the intrinsic size of the layer, returns the pixel boundaries of the layer rect. - */ - protected RectF getBounds(RenderContext context, FloatSize size) { - float scaleFactor = context.zoomFactor / mResolution; - float x = mOrigin.x * scaleFactor, y = mOrigin.y * scaleFactor; - float width = size.width * scaleFactor, height = size.height * scaleFactor; - return new RectF(x, y, x + width, y + height); - } - - /** - * Returns the region of the layer that is considered valid. The default - * implementation of this will return the bounds of the layer, but this - * may be overridden. - */ - public Region getValidRegion(RenderContext context) { - return new Region(RectUtils.round(getBounds(context, new FloatSize(getSize())))); - } - - /** - * Call this before modifying the layer. Note that, for TileLayers, "modifying the layer" - * includes altering the underlying CairoImage in any way. Thus you must call this function - * before modifying the byte buffer associated with this layer. - *

- * This function may block, so you should never call this on the main UI thread. - */ - public void beginTransaction(LayerView aView) { - //if (mTransactionLock.isHeldByCurrentThread()) - // throw new RuntimeException("Nested transactions are not supported"); - mTransactionLock.lock(); - mView = aView; - mInTransaction = true; - mNewResolution = mResolution; - } - - public void beginTransaction() { - beginTransaction(null); - } - - /** - * Call this when you're done modifying the layer. - */ - public void endTransaction() { - if (!mInTransaction) - throw new RuntimeException("endTransaction() called outside a transaction"); - mInTransaction = false; - mTransactionLock.unlock(); - - if (mView != null) - mView.requestRender(); - } - - /** - * Returns true if the layer is currently in a transaction and false otherwise. - */ - protected boolean inTransaction() { - return mInTransaction; - } - - /** - * Returns the current layer origin. - */ - public Point getOrigin() { - return mOrigin; - } - - /** - * Sets the origin. Only valid inside a transaction. - */ - public void setOrigin(Point newOrigin) { - if (!mInTransaction) - throw new RuntimeException("setOrigin() is only valid inside a transaction"); - mNewOrigin = newOrigin; - } - - /** - * Returns the current layer's resolution. - */ - public float getResolution() { - return mResolution; - } - - /** - * Sets the layer resolution. This value is used to determine how many pixels per - * device pixel this layer was rendered at. This will be reflected by scaling by - * the reciprocal of the resolution in the layer's transform() function. - * Only valid inside a transaction. - */ - public void setResolution(float newResolution) { - if (!mInTransaction) - throw new RuntimeException("setResolution() is only valid inside a transaction"); - mNewResolution = newResolution; - } - - /** - * Subclasses may override this method to perform custom layer updates. This will be called - * with the transaction lock held. Subclass implementations of this method must call the - * superclass implementation. Returns false if there is still work to be done after this - * update is complete. - */ - protected boolean performUpdates(RenderContext context) { - if (mNewOrigin != null) { - mOrigin = mNewOrigin; - mNewOrigin = null; - } - if (mNewResolution != 0.0f) { - mResolution = mNewResolution; - mNewResolution = 0.0f; - } - - return true; - } - - protected boolean dimensionChangesPending() { - return (mNewOrigin != null) || (mNewResolution != 0.0f); - } - - public static class RenderContext { - public final RectF viewport; - public final FloatSize pageSize; - public final float zoomFactor; - public final int positionHandle; - public final int textureHandle; - public final FloatBuffer coordBuffer; - - public RenderContext(RectF aViewport, FloatSize aPageSize, float aZoomFactor, - int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) { - viewport = aViewport; - pageSize = aPageSize; - zoomFactor = aZoomFactor; - positionHandle = aPositionHandle; - textureHandle = aTextureHandle; - coordBuffer = aCoordBuffer; - } - - public boolean fuzzyEquals(RenderContext other) { - if (other == null) { - return false; - } - return RectUtils.fuzzyEquals(viewport, other.viewport) - && pageSize.fuzzyEquals(other.pageSize) - && FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java deleted file mode 100644 index 4f461088203e..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerClient.java +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -/** - * A layer client provides tiles and manages other information used by the layer controller. - */ -public abstract class LayerClient { - private LayerController mLayerController; - - public abstract void geometryChanged(); - - public abstract void viewportSizeChanged(); - - protected abstract void render(); - - public LayerController getLayerController() { - return mLayerController; - } - - public void setLayerController(LayerController layerController) { - mLayerController = layerController; - } - - /** - * A utility function for calling Layer.beginTransaction with the - * appropriate LayerView. - */ - public void beginTransaction(Layer aLayer) { - if (mLayerController != null) { - LayerView view = mLayerController.getView(); - if (view != null) { - aLayer.beginTransaction(view); - return; - } - } - - aLayer.beginTransaction(); - } - - // Included for symmetry. - public void endTransaction(Layer aLayer) { - aLayer.endTransaction(); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java deleted file mode 100644 index 250dc84c69fe..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerController.java +++ /dev/null @@ -1,534 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View.OnTouchListener; - -import org.mozilla.gecko.ui.PanZoomController; -import org.mozilla.gecko.ui.SimpleScaleGestureDetector; - -import java.util.Timer; -import java.util.TimerTask; - -/** - * The layer controller manages a tile that represents the visible page. It does panning and - * zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched - * to a higher-level view. - *

- * Many methods require that the monitor be held, with a synchronized (controller) { ... } block. - */ -public class LayerController { - /* The extra area on the sides of the page that we want to buffer to help with - * smooth, asynchronous scrolling. Depending on a device's support for NPOT - * textures, this may be rounded up to the nearest power of two. - */ - public static final IntSize MIN_BUFFER = new IntSize(512, 1024); - private static final String LOGTAG = "GeckoLayerController"; - /* If the visible rect is within the danger zone (measured in pixels from each edge of a tile), - * we start aggressively redrawing to minimize checkerboarding. */ - private static final int DANGER_ZONE_X = 75; - private static final int DANGER_ZONE_Y = 150; - /* The time limit for pages to respond with preventDefault on touchevents - * before we begin panning the page */ - private static final int PREVENT_DEFAULT_TIMEOUT = 200; - private Layer mRootLayer; /* The root layer. */ - private LayerView mView; /* The main rendering view. */ - /* - * The panning and zooming controller, which interprets pan and zoom gestures for us and - * updates our visible rect appropriately. - */ - private Context mContext; /* The current context. */ - private ViewportMetrics mViewportMetrics; /* The current viewport metrics. */ - private boolean mWaitForTouchListeners; - private PanZoomController mPanZoomController; - private OnTouchListener mOnTouchListener; /* The touch listener. */ - private LayerClient mLayerClient; /* The layer client. */ - /* The new color for the checkerboard. */ - private int mCheckerboardColor; - private boolean mCheckerboardShouldShowChecks; - private boolean mForceRedraw; - private boolean allowDefaultActions = true; - private Timer allowDefaultTimer = null; - private boolean inTouchSession = false; - private PointF initialTouchLocation = null; - - public LayerController(Context context) { - mContext = context; - - mForceRedraw = true; - mViewportMetrics = new ViewportMetrics(); - mPanZoomController = new PanZoomController(this); - mView = new LayerView(context, this); - } - - public void setForceRedraw() { - mForceRedraw = true; - } - - public LayerClient getLayerClient() { - return mLayerClient; - } - - public void setLayerClient(LayerClient layerClient) { - mLayerClient = layerClient; - layerClient.setLayerController(this); - } - - public Layer getRoot() { - return mRootLayer; - } - - public void setRoot(Layer layer) { - mRootLayer = layer; - } - - public LayerView getView() { - return mView; - } - - public Context getContext() { - return mContext; - } - - public ViewportMetrics getViewportMetrics() { - return mViewportMetrics; - } - - /** - * Sets the entire viewport metrics at once. This function does not notify the layer client or - * the pan/zoom controller, so you will need to call notifyLayerClientOfGeometryChange() or - * notifyPanZoomControllerOfGeometryChange() after calling this. You must hold the monitor - * while calling this. - */ - public void setViewportMetrics(ViewportMetrics viewport) { - mViewportMetrics = new ViewportMetrics(viewport); - Log.d(LOGTAG, "setViewportMetrics: " + mViewportMetrics); - // this function may or may not be called on the UI thread, - // but repositionPluginViews must only be called on the UI thread. - //GeckoApp.mAppContext.runOnUiThread(new Runnable() { - // public void run() { - // GeckoApp.mAppContext.repositionPluginViews(false); - // } - //}); - mView.requestRender(); - } - - public RectF getViewport() { - return mViewportMetrics.getViewport(); - } - - public FloatSize getViewportSize() { - return mViewportMetrics.getSize(); - } - - /** - * The view calls this function to indicate that the viewport changed size. It must hold the - * monitor while calling it. - *

- * TODO: Refactor this to use an interface. Expose that interface only to the view and not - * to the layer client. That way, the layer client won't be tempted to call this, which might - * result in an infinite loop. - */ - public void setViewportSize(FloatSize size) { - // Resize the viewport, and modify its zoom factor so that the page retains proportionally - // zoomed relative to the screen. - float oldHeight = mViewportMetrics.getSize().height; - float oldWidth = mViewportMetrics.getSize().width; - float oldZoomFactor = mViewportMetrics.getZoomFactor(); - mViewportMetrics.setSize(size); - - // if the viewport got larger (presumably because the vkb went away), and the page - // is smaller than the new viewport size, increase the page size so that the panzoomcontroller - // doesn't zoom in to make it fit (bug 718270). this page size change is in anticipation of - // gecko increasing the page size to match the new viewport size, which will happen the next - // time we get a draw update. - if (size.width >= oldWidth && size.height >= oldHeight) { - FloatSize pageSize = mViewportMetrics.getPageSize(); - if (pageSize.width < size.width || pageSize.height < size.height) { - mViewportMetrics.setPageSize(new FloatSize(Math.max(pageSize.width, size.width), - Math.max(pageSize.height, size.height))); - } - } - - PointF newFocus = new PointF(size.width / 2.0f, size.height / 2.0f); - float newZoomFactor = size.width * oldZoomFactor / oldWidth; - mViewportMetrics.scaleTo(newZoomFactor, newFocus); - - Log.d(LOGTAG, "setViewportSize: " + mViewportMetrics); - setForceRedraw(); - - if (mLayerClient != null) - mLayerClient.viewportSizeChanged(); - - notifyLayerClientOfGeometryChange(); - mPanZoomController.abortAnimation(); - mView.requestRender(); - } - - public FloatSize getPageSize() { - return mViewportMetrics.getPageSize(); - } - - /** - * Sets the current page size. You must hold the monitor while calling this. - */ - public void setPageSize(FloatSize size) { - if (mViewportMetrics.getPageSize().fuzzyEquals(size)) - return; - - mViewportMetrics.setPageSize(size); - Log.d(LOGTAG, "setPageSize: " + mViewportMetrics); - - // Page size is owned by the LayerClient, so no need to notify it of - // this change. - - mView.post(new Runnable() { - public void run() { - mPanZoomController.pageSizeUpdated(); - mView.requestRender(); - } - }); - } - - public PointF getOrigin() { - return mViewportMetrics.getOrigin(); - } - - public float getZoomFactor() { - return mViewportMetrics.getZoomFactor(); - } - - public Bitmap getBackgroundPattern() { - return getDrawable("background"); - } - - public Bitmap getShadowPattern() { - return getDrawable("shadow"); - } - - public PanZoomController getPanZoomController() { - return mPanZoomController; - } - - public GestureDetector.OnGestureListener getGestureListener() { - return mPanZoomController; - } - - public SimpleScaleGestureDetector.SimpleScaleGestureListener getScaleGestureListener() { - return mPanZoomController; - } - - public GestureDetector.OnDoubleTapListener getDoubleTapListener() { - return mPanZoomController; - } - - public Bitmap getDrawable(String name) { - Resources resources = mContext.getResources(); - int resourceID = resources.getIdentifier(name, "drawable", mContext.getPackageName()); - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inScaled = false; - return BitmapFactory.decodeResource(mContext.getResources(), resourceID, options); - } - - public Bitmap getDrawable16(String name) { - Resources resources = mContext.getResources(); - int resourceID = resources.getIdentifier(name, "drawable", mContext.getPackageName()); - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inScaled = false; - options.inPreferredConfig = Bitmap.Config.RGB_565; - return BitmapFactory.decodeResource(mContext.getResources(), resourceID, options); - } - - /** - * Scrolls the viewport by the given offset. You must hold the monitor while calling this. - */ - public void scrollBy(PointF point) { - PointF origin = mViewportMetrics.getOrigin(); - origin.offset(point.x, point.y); - mViewportMetrics.setOrigin(origin); - Log.d(LOGTAG, "scrollBy: " + mViewportMetrics); - - notifyLayerClientOfGeometryChange(); - //GeckoApp.mAppContext.repositionPluginViews(false); - mView.requestRender(); - } - - /** - * Scales the viewport, keeping the given focus point in the same place before and after the - * scale operation. You must hold the monitor while calling this. - */ - public void scaleWithFocus(float zoomFactor, PointF focus) { - mViewportMetrics.scaleTo(zoomFactor, focus); - Log.d(LOGTAG, "scaleWithFocus: " + mViewportMetrics + "; zf=" + zoomFactor); - - // We assume the zoom level will only be modified by the - // PanZoomController, so no need to notify it of this change. - notifyLayerClientOfGeometryChange(); - //GeckoApp.mAppContext.repositionPluginViews(false); - mView.requestRender(); - } - - public boolean post(Runnable action) { - return mView.post(action); - } - - public void setOnTouchListener(OnTouchListener onTouchListener) { - mOnTouchListener = onTouchListener; - } - - /** - * The view as well as the controller itself use this method to notify the layer client that - * the geometry changed. - */ - public void notifyLayerClientOfGeometryChange() { - if (mLayerClient != null) - mLayerClient.geometryChanged(); - } - - /** - * Aborts any pan/zoom animation that is currently in progress. - */ - public void abortPanZoomAnimation() { - if (mPanZoomController != null) { - mView.post(new Runnable() { - public void run() { - mPanZoomController.abortAnimation(); - } - }); - } - } - - /** - * Returns true if this controller is fine with performing a redraw operation or false if it - * would prefer that the action didn't take place. - */ - public boolean getRedrawHint() { - // FIXME: Allow redraw while a finger is down, but only if we're about to checkerboard. - // This requires fixing aboutToCheckerboard() to know about the new buffer size. - - if (mForceRedraw) { - mForceRedraw = false; - return true; - } - - return mPanZoomController.getRedrawHint(); - } - - private RectF getTileRect() { - if (mRootLayer == null) - return new RectF(); - - float x = mRootLayer.getOrigin().x, y = mRootLayer.getOrigin().y; - IntSize layerSize = mRootLayer.getSize(); - return new RectF(x, y, x + layerSize.width, y + layerSize.height); - } - - // Returns true if a checkerboard is about to be visible. - private boolean aboutToCheckerboard() { - // Increase the size of the viewport (and clamp to page boundaries), and - // intersect it with the tile's displayport to determine whether we're - // close to checkerboarding. - FloatSize pageSize = getPageSize(); - RectF adjustedViewport = RectUtils.expand(getViewport(), DANGER_ZONE_X, DANGER_ZONE_Y); - if (adjustedViewport.top < 0) adjustedViewport.top = 0; - if (adjustedViewport.left < 0) adjustedViewport.left = 0; - if (adjustedViewport.right > pageSize.width) adjustedViewport.right = pageSize.width; - if (adjustedViewport.bottom > pageSize.height) adjustedViewport.bottom = pageSize.height; - - return !getTileRect().contains(adjustedViewport); - } - - /** - * Converts a point from layer view coordinates to layer coordinates. In other words, given a - * point measured in pixels from the top left corner of the layer view, returns the point in - * pixels measured from the top left corner of the root layer, in the coordinate system of the - * layer itself. This method is used by the viewport controller as part of the process of - * translating touch events to Gecko's coordinate system. - */ - public PointF convertViewPointToLayerPoint(PointF viewPoint) { - if (mRootLayer == null) - return null; - - // Undo the transforms. - PointF origin = mViewportMetrics.getOrigin(); - PointF newPoint = new PointF(origin.x, origin.y); - newPoint.offset(viewPoint.x, viewPoint.y); - - Point rootOrigin = mRootLayer.getOrigin(); - newPoint.offset(-rootOrigin.x, -rootOrigin.y); - - return newPoint; - } - - /* - * Gesture detection. This is handled only at a high level in this class; we dispatch to the - * pan/zoom controller to do the dirty work. - */ - public boolean onTouchEvent(MotionEvent event) { - int action = event.getAction(); - PointF point = new PointF(event.getX(), event.getY()); - - if ((action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN) { - mView.clearEventQueue(); - initialTouchLocation = point; - allowDefaultActions = !mWaitForTouchListeners; - post(new Runnable() { - public void run() { - preventPanning(mWaitForTouchListeners); - } - }); - } - - // After the initial touch, ignore touch moves until they exceed a minimum distance. - if (initialTouchLocation != null && (action & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE) { - if (PointUtils.subtract(point, initialTouchLocation).length() > PanZoomController.PAN_THRESHOLD) { - initialTouchLocation = null; - } else { - return !allowDefaultActions; - } - } - - if (mOnTouchListener != null) - mOnTouchListener.onTouch(mView, event); - - if (!mWaitForTouchListeners) - return !allowDefaultActions; - - boolean createTimer = false; - switch (action & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_MOVE: { - if (!inTouchSession && allowDefaultTimer == null) { - inTouchSession = true; - createTimer = true; - } - break; - } - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: { - // if we still have initialTouchLocation, we haven't fired any - // touchmove events. We should start the timer to wait for preventDefault - // from touchstart. If we don't hear from it we fire mouse events - if (initialTouchLocation != null) - createTimer = true; - inTouchSession = false; - } - } - - if (createTimer) { - if (allowDefaultTimer != null) { - allowDefaultTimer.cancel(); - } - allowDefaultTimer = new Timer(); - allowDefaultTimer.schedule(new TimerTask() { - public void run() { - post(new Runnable() { - public void run() { - preventPanning(false); - } - }); - } - }, PREVENT_DEFAULT_TIMEOUT); - } - - return !allowDefaultActions; - } - - public void preventPanning(boolean aValue) { - if (allowDefaultTimer != null) { - allowDefaultTimer.cancel(); - allowDefaultTimer.purge(); - allowDefaultTimer = null; - } - if (aValue == allowDefaultActions) { - allowDefaultActions = !aValue; - - if (aValue) { - mView.clearEventQueue(); - mPanZoomController.cancelTouch(); - } else { - mView.processEventQueue(); - } - } - } - - public void setWaitForTouchListeners(boolean aValue) { - mWaitForTouchListeners = aValue; - } - - /** - * Retrieves whether we should show checkerboard checks or not. - */ - public boolean checkerboardShouldShowChecks() { - return mCheckerboardShouldShowChecks; - } - - /** - * Retrieves the color that the checkerboard should be. - */ - public int getCheckerboardColor() { - return mCheckerboardColor; - } - - /** - * Sets a new color for the checkerboard. - */ - public void setCheckerboardColor(int newColor) { - mCheckerboardColor = newColor; - mView.requestRender(); - } - - /** - * Sets whether or not the checkerboard should show checkmarks. - */ - public void setCheckerboardShowChecks(boolean showChecks) { - mCheckerboardShouldShowChecks = showChecks; - mView.requestRender(); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java deleted file mode 100644 index 6690aad8ec16..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerRenderer.java +++ /dev/null @@ -1,689 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.gfx.BufferedCairoImage; -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.Layer.RenderContext; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.NinePatchTileLayer; -import org.mozilla.gecko.gfx.SingleTileLayer; -import org.mozilla.gecko.gfx.TextureReaper; -import org.mozilla.gecko.gfx.TextureGenerator; -import org.mozilla.gecko.gfx.TextLayer; -import org.mozilla.gecko.gfx.TileLayer; -//import org.mozilla.gecko.GeckoAppShell; -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; -import android.graphics.RegionIterator; -import android.opengl.GLES20; -import android.opengl.GLSurfaceView; -import android.os.SystemClock; -import android.util.DisplayMetrics; -import android.util.Log; -import android.view.WindowManager; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; - -/** - * The layer renderer implements the rendering logic for a layer view. - */ -public class LayerRenderer implements GLSurfaceView.Renderer { - private static final String LOGTAG = "GeckoLayerRenderer"; - private static final String PROFTAG = "GeckoLayerRendererProf"; - - /* - * The amount of time a frame is allowed to take to render before we declare it a dropped - * frame. - */ - private static final int MAX_FRAME_TIME = 16; /* 1000 ms / 60 FPS */ - - private static final int FRAME_RATE_METER_WIDTH = 64; - private static final int FRAME_RATE_METER_HEIGHT = 32; - - private final LayerView mView; - private final SingleTileLayer mBackgroundLayer; - private final CheckerboardImage mCheckerboardImage; - private final SingleTileLayer mCheckerboardLayer; - private final NinePatchTileLayer mShadowLayer; - private final TextLayer mFrameRateLayer; - private final ScrollbarLayer mHorizScrollLayer; - private final ScrollbarLayer mVertScrollLayer; - private final FadeRunnable mFadeRunnable; - private final FloatBuffer mCoordBuffer; - private RenderContext mLastPageContext; - private int mMaxTextureSize; - - private ArrayList mExtraLayers = new ArrayList(); - - // Dropped frames display - private int[] mFrameTimings; - private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames; - private boolean mShowFrameRate; - - // Render profiling output - private int mFramesRendered; - private float mCompleteFramesRendered; - private boolean mProfileRender; - private long mProfileOutputTime; - - /* Used by robocop for testing purposes */ - private IntBuffer mPixelBuffer; - - // Used by GLES 2.0 - private int mProgram; - private int mPositionHandle; - private int mTextureHandle; - private int mSampleHandle; - private int mTMatrixHandle; - - // column-major matrix applied to each vertex to shift the viewport from - // one ranging from (-1, -1),(1,1) to (0,0),(1,1) and to scale all sizes by - // a factor of 2 to fill up the screen - private static final float[] TEXTURE_MATRIX = { - 2.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 2.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 2.0f, 0.0f, - -1.0f, -1.0f, 0.0f, 1.0f - }; - - private static final int COORD_BUFFER_SIZE = 20; - - // The shaders run on the GPU directly, the vertex shader is only applying the - // matrix transform detailed above - private static final String VERTEX_SHADER = - "uniform mat4 uTMatrix;\n" + - "attribute vec4 vPosition;\n" + - "attribute vec2 aTexCoord;\n" + - "varying vec2 vTexCoord;\n" + - "void main() {\n" + - " gl_Position = uTMatrix * vPosition;\n" + - " vTexCoord = aTexCoord;\n" + - "}\n"; - - // Note we flip the y-coordinate in the fragment shader from a - // coordinate system with (0,0) in the top left to one with (0,0) in - // the bottom left. - private static final String FRAGMENT_SHADER = - "precision mediump float;\n" + - "varying vec2 vTexCoord;\n" + - "uniform sampler2D sTexture;\n" + - "void main() {\n" + - " gl_FragColor = texture2D(sTexture, vec2(vTexCoord.x, 1.0 - vTexCoord.y));\n" + - "}\n"; - - public LayerRenderer(LayerView view) { - mView = view; - - LayerController controller = view.getController(); - - CairoImage backgroundImage = new BufferedCairoImage(controller.getBackgroundPattern()); - mBackgroundLayer = new SingleTileLayer(true, backgroundImage); - - mCheckerboardImage = new CheckerboardImage(); - mCheckerboardLayer = new SingleTileLayer(true, mCheckerboardImage); - - CairoImage shadowImage = new BufferedCairoImage(controller.getShadowPattern()); - mShadowLayer = new NinePatchTileLayer(shadowImage); - - IntSize frameRateLayerSize = new IntSize(FRAME_RATE_METER_WIDTH, FRAME_RATE_METER_HEIGHT); - mFrameRateLayer = TextLayer.create(frameRateLayerSize, "-- ms/--"); - - mHorizScrollLayer = ScrollbarLayer.create(false); - mVertScrollLayer = ScrollbarLayer.create(true); - mFadeRunnable = new FadeRunnable(); - - mFrameTimings = new int[60]; - mCurrentFrame = mFrameTimingsSum = mDroppedFrames = 0; - mShowFrameRate = false; - - // Initialize the FloatBuffer that will be used to store all vertices and texture - // coordinates in draw() commands. - ByteBuffer byteBuffer = LOKitShell.allocateDirectBuffer(COORD_BUFFER_SIZE * 4); - byteBuffer.order(ByteOrder.nativeOrder()); - mCoordBuffer = byteBuffer.asFloatBuffer(); - } - - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - checkMonitoringEnabled(); - createProgram(); - activateProgram(); - } - - public void createProgram() { - int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER); - int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER); - - mProgram = GLES20.glCreateProgram(); - GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program - GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program - GLES20.glLinkProgram(mProgram); // creates OpenGL program executables - - // Get handles to the vertex shader's vPosition, aTexCoord, sTexture, and uTMatrix members. - mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); - mTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTexCoord"); - mSampleHandle = GLES20.glGetUniformLocation(mProgram, "sTexture"); - mTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uTMatrix"); - - int maxTextureSizeResult[] = new int[1]; - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0); - mMaxTextureSize = maxTextureSizeResult[0]; - } - - // Activates the shader program. - public void activateProgram() { - // Add the program to the OpenGL environment - GLES20.glUseProgram(mProgram); - - // Set the transformation matrix - GLES20.glUniformMatrix4fv(mTMatrixHandle, 1, false, TEXTURE_MATRIX, 0); - - Log.e(LOGTAG, "### Position handle is " + mPositionHandle + ", texture handle is " + - mTextureHandle + ", last error is " + GLES20.glGetError()); - - // Enable the arrays from which we get the vertex and texture coordinates - GLES20.glEnableVertexAttribArray(mPositionHandle); - GLES20.glEnableVertexAttribArray(mTextureHandle); - - GLES20.glUniform1i(mSampleHandle, 0); - - TextureGenerator.get().fill(); - - // TODO: Move these calls into a separate deactivate() call that is called after the - // underlay and overlay are rendered. - } - - // Deactivates the shader program. This must be done to avoid crashes after returning to the - // Gecko C++ compositor from Java. - public void deactivateProgram() { - GLES20.glDisableVertexAttribArray(mTextureHandle); - GLES20.glDisableVertexAttribArray(mPositionHandle); - GLES20.glUseProgram(0); - } - - public int getMaxTextureSize() { - return mMaxTextureSize; - } - - public void addLayer(Layer layer) { - LayerController controller = mView.getController(); - - synchronized (controller) { - if (mExtraLayers.contains(layer)) { - mExtraLayers.remove(layer); - } - - mExtraLayers.add(layer); - } - } - - public void removeLayer(Layer layer) { - LayerController controller = mView.getController(); - - synchronized (controller) { - mExtraLayers.remove(layer); - } - } - - /** - * Called whenever a new frame is about to be drawn. - */ - public void onDrawFrame(GL10 gl) { - RenderContext pageContext = createPageContext(), screenContext = createScreenContext(); - Frame frame = createFrame(pageContext, screenContext); - synchronized (mView.getController()) { - frame.beginDrawing(); - frame.drawBackground(); - frame.drawRootLayer(); - frame.drawForeground(); - frame.endDrawing(); - } - } - - private void printCheckerboardStats() { - Log.d(PROFTAG, "Frames rendered over last 1000ms: " + mCompleteFramesRendered + "/" + mFramesRendered); - mFramesRendered = 0; - mCompleteFramesRendered = 0; - } - - /** Used by robocop for testing purposes. Not for production use! */ - IntBuffer getPixels() { - IntBuffer pixelBuffer = IntBuffer.allocate(mView.getWidth() * mView.getHeight()); - synchronized (pixelBuffer) { - mPixelBuffer = pixelBuffer; - mView.requestRender(); - try { - pixelBuffer.wait(); - } catch (InterruptedException ie) { - } - mPixelBuffer = null; - } - return pixelBuffer; - } - - public RenderContext createScreenContext() { - LayerController layerController = mView.getController(); - IntSize viewportSize = new IntSize(layerController.getViewportSize()); - RectF viewport = new RectF(0.0f, 0.0f, viewportSize.width, viewportSize.height); - FloatSize pageSize = new FloatSize(layerController.getPageSize()); - return createContext(viewport, pageSize, 1.0f); - } - - public RenderContext createPageContext() { - LayerController layerController = mView.getController(); - - Rect viewport = new Rect(); - layerController.getViewport().round(viewport); - - FloatSize pageSize = new FloatSize(layerController.getPageSize()); - float zoomFactor = layerController.getZoomFactor(); - return createContext(new RectF(viewport), pageSize, zoomFactor); - } - - private RenderContext createContext(RectF viewport, FloatSize pageSize, float zoomFactor) { - return new RenderContext(viewport, pageSize, zoomFactor, mPositionHandle, mTextureHandle, - mCoordBuffer); - } - - private Rect getPageRect() { - LayerController controller = mView.getController(); - - Point origin = PointUtils.round(controller.getOrigin()); - IntSize pageSize = new IntSize(controller.getPageSize()); - - origin.negate(); - - return new Rect(origin.x, origin.y, - origin.x + pageSize.width, origin.y + pageSize.height); - } - - private Rect transformToScissorRect(Rect rect) { - LayerController controller = mView.getController(); - IntSize screenSize = new IntSize(controller.getViewportSize()); - - int left = Math.max(0, rect.left); - int top = Math.max(0, rect.top); - int right = Math.min(screenSize.width, rect.right); - int bottom = Math.min(screenSize.height, rect.bottom); - - return new Rect(left, screenSize.height - bottom, right, - (screenSize.height - bottom) + (bottom - top)); - } - - public void onSurfaceChanged(GL10 gl, final int width, final int height) { - GLES20.glViewport(0, 0, width, height); - - // updating the state in the view/controller/client should be - // done on the main UI thread, not the GL renderer thread - mView.post(new Runnable() { - public void run() { - mView.setViewportSize(new IntSize(width, height)); - moveFrameRateLayer(width, height); - } - }); - - /* TODO: Throw away tile images? */ - } - - private void updateDroppedFrames(long frameStartTime) { - int frameElapsedTime = (int)(SystemClock.uptimeMillis() - frameStartTime); - - /* Update the running statistics. */ - mFrameTimingsSum -= mFrameTimings[mCurrentFrame]; - mFrameTimingsSum += frameElapsedTime; - mDroppedFrames -= (mFrameTimings[mCurrentFrame] + 1) / MAX_FRAME_TIME; - mDroppedFrames += (frameElapsedTime + 1) / MAX_FRAME_TIME; - - mFrameTimings[mCurrentFrame] = frameElapsedTime; - mCurrentFrame = (mCurrentFrame + 1) % mFrameTimings.length; - - int averageTime = mFrameTimingsSum / mFrameTimings.length; - mFrameRateLayer.beginTransaction(); - try { - mFrameRateLayer.setText(averageTime + " ms/" + mDroppedFrames); - } finally { - mFrameRateLayer.endTransaction(); - } - } - - /* Given the new dimensions for the surface, moves the frame rate layer appropriately. */ - private void moveFrameRateLayer(int width, int height) { - mFrameRateLayer.beginTransaction(); - try { - Point origin = new Point(width - FRAME_RATE_METER_WIDTH - 8, - height - FRAME_RATE_METER_HEIGHT + 8); - mFrameRateLayer.setOrigin(origin); - } finally { - mFrameRateLayer.endTransaction(); - } - } - - private void checkMonitoringEnabled() { - /* Do this I/O off the main thread to minimize its impact on startup time. */ - new Thread(new Runnable() { - @Override - public void run() { - Context context = mView.getContext(); - SharedPreferences preferences = context.getSharedPreferences("GeckoApp", 0); - mShowFrameRate = preferences.getBoolean("showFrameRate", false); - mProfileRender = Log.isLoggable(PROFTAG, Log.DEBUG); - } - }).start(); - } - - private void updateCheckerboardLayer(RenderContext renderContext) { - int checkerboardColor = mView.getController().getCheckerboardColor(); - boolean showChecks = mView.getController().checkerboardShouldShowChecks(); - if (checkerboardColor == mCheckerboardImage.getColor() && - showChecks == mCheckerboardImage.getShowChecks()) { - return; - } - - mCheckerboardLayer.beginTransaction(); - try { - mCheckerboardImage.update(showChecks, checkerboardColor); - mCheckerboardLayer.invalidate(); - } finally { - mCheckerboardLayer.endTransaction(); - } - - mCheckerboardLayer.update(renderContext); - } - - /* - * create a vertex shader type (GLES20.GL_VERTEX_SHADER) - * or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) - */ - private int loadShader(int type, String shaderCode) { - int shader = GLES20.glCreateShader(type); - GLES20.glShaderSource(shader, shaderCode); - GLES20.glCompileShader(shader); - return shader; - } - - public Frame createFrame(RenderContext pageContext, RenderContext screenContext) { - return new Frame(pageContext, screenContext); - } - - class FadeRunnable implements Runnable { - private boolean mStarted; - private long mRunAt; - - void scheduleStartFade(long delay) { - mRunAt = SystemClock.elapsedRealtime() + delay; - if (!mStarted) { - mView.postDelayed(this, delay); - mStarted = true; - } - } - - void scheduleNextFadeFrame() { - if (mStarted) { - Log.e(LOGTAG, "scheduleNextFadeFrame() called while scheduled for starting fade"); - } - mView.postDelayed(this, 1000L / 60L); // request another frame at 60fps - } - - boolean timeToFade() { - return !mStarted; - } - - public void run() { - long timeDelta = mRunAt - SystemClock.elapsedRealtime(); - if (timeDelta > 0) { - // the run-at time was pushed back, so reschedule - mView.postDelayed(this, timeDelta); - } else { - // reached the run-at time, execute - mStarted = false; - mView.requestRender(); - } - } - } - - public class Frame { - // The timestamp recording the start of this frame. - private long mFrameStartTime; - // A rendering context for page-positioned layers, and one for screen-positioned layers. - private RenderContext mPageContext, mScreenContext; - // Whether a layer was updated. - private boolean mUpdated; - - public Frame(RenderContext pageContext, RenderContext screenContext) { - mPageContext = pageContext; - mScreenContext = screenContext; - } - - private void setScissorRect() { - Rect scissorRect = transformToScissorRect(getPageRect()); - GLES20.glEnable(GLES20.GL_SCISSOR_TEST); - GLES20.glScissor(scissorRect.left, scissorRect.top, - scissorRect.width(), scissorRect.height()); - } - - public void beginDrawing() { - mFrameStartTime = SystemClock.uptimeMillis(); - - TextureReaper.get().reap(); - TextureGenerator.get().fill(); - - mUpdated = true; - - LayerController controller = mView.getController(); - Layer rootLayer = controller.getRoot(); - - if (!mPageContext.fuzzyEquals(mLastPageContext)) { - // the viewport or page changed, so show the scrollbars again - // as per UX decision - mVertScrollLayer.unfade(); - mHorizScrollLayer.unfade(); - mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY); - } else if (mFadeRunnable.timeToFade()) { - boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade(); - if (stillFading) { - mFadeRunnable.scheduleNextFadeFrame(); - } - } - mLastPageContext = mPageContext; - - /* Update layers. */ - if (rootLayer != null) mUpdated &= rootLayer.update(mPageContext); - mUpdated &= mBackgroundLayer.update(mScreenContext); - mUpdated &= mShadowLayer.update(mPageContext); - updateCheckerboardLayer(mScreenContext); - mUpdated &= mFrameRateLayer.update(mScreenContext); - mUpdated &= mVertScrollLayer.update(mPageContext); - mUpdated &= mHorizScrollLayer.update(mPageContext); - - for (Layer layer : mExtraLayers) - mUpdated &= layer.update(mPageContext); - - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - - // If a layer update requires further work, schedule another redraw - if (!mUpdated) - mView.requestRender(); - - PanningPerfAPI.recordFrameTime(); - - /* Used by robocop for testing purposes */ - IntBuffer pixelBuffer = mPixelBuffer; - if (mUpdated && pixelBuffer != null) { - synchronized (pixelBuffer) { - pixelBuffer.position(0); - GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(), - (int)mScreenContext.viewport.height(), GLES20.GL_RGBA, - GLES20.GL_UNSIGNED_BYTE, pixelBuffer); - pixelBuffer.notify(); - } - } - } - - public void drawBackground() { - /* Draw the background. */ - mBackgroundLayer.draw(mScreenContext); - - /* Draw the drop shadow, if we need to. */ - Rect pageRect = getPageRect(); - RectF untransformedPageRect = new RectF(0.0f, 0.0f, pageRect.width(), - pageRect.height()); - if (!untransformedPageRect.contains(mView.getController().getViewport())) - mShadowLayer.draw(mPageContext); - - /* Draw the checkerboard. */ - setScissorRect(); - mCheckerboardLayer.draw(mScreenContext); - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - } - - // Draws the layer the client added to us. - void drawRootLayer() { - Layer rootLayer = mView.getController().getRoot(); - if (rootLayer == null) { - return; - } - - setScissorRect(); - rootLayer.draw(mPageContext); - GLES20.glDisable(GLES20.GL_SCISSOR_TEST); - } - - public void drawForeground() { - Rect pageRect = getPageRect(); - LayerController controller = mView.getController(); - - /* Draw any extra layers that were added (likely plugins) */ - for (Layer layer : mExtraLayers) - layer.draw(mPageContext); - - /* Draw the vertical scrollbar. */ - IntSize screenSize = new IntSize(controller.getViewportSize()); - if (pageRect.height() > screenSize.height) - mVertScrollLayer.draw(mPageContext); - - /* Draw the horizontal scrollbar. */ - if (pageRect.width() > screenSize.width) - mHorizScrollLayer.draw(mPageContext); - - /* Measure how much of the screen is checkerboarding */ - Layer rootLayer = controller.getRoot(); - if ((rootLayer != null) && - (mProfileRender || PanningPerfAPI.isRecordingCheckerboard())) { - // Find out how much of the viewport area is valid - Rect viewport = RectUtils.round(mPageContext.viewport); - Region validRegion = rootLayer.getValidRegion(mPageContext); - validRegion.op(viewport, Region.Op.INTERSECT); - - float checkerboard = 0.0f; - if (!(validRegion.isRect() && validRegion.getBounds().equals(viewport))) { - int screenArea = viewport.width() * viewport.height(); - validRegion.op(viewport, Region.Op.REVERSE_DIFFERENCE); - - // XXX The assumption here is that a Region never has overlapping - // rects. This is true, as evidenced by reading the SkRegion - // source, but is not mentioned in the Android documentation, - // and so is liable to change. - // If it does change, this code will need to be reevaluated. - Rect r = new Rect(); - int checkerboardArea = 0; - for (RegionIterator i = new RegionIterator(validRegion); i.next(r);) { - checkerboardArea += r.width() * r.height(); - } - - checkerboard = checkerboardArea / (float)screenArea; - } - - PanningPerfAPI.recordCheckerboard(checkerboard); - - mCompleteFramesRendered += 1.0f - checkerboard; - mFramesRendered ++; - - if (mFrameStartTime - mProfileOutputTime > 1000) { - mProfileOutputTime = mFrameStartTime; - printCheckerboardStats(); - } - } - - /* Draw the FPS. */ - if (mShowFrameRate) { - updateDroppedFrames(mFrameStartTime); - - try { - GLES20.glEnable(GLES20.GL_BLEND); - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); - mFrameRateLayer.draw(mScreenContext); - } finally { - GLES20.glDisable(GLES20.GL_BLEND); - } - } - } - - public void endDrawing() { - // If a layer update requires further work, schedule another redraw - if (!mUpdated) - mView.requestRender(); - - PanningPerfAPI.recordFrameTime(); - - /* Used by robocop for testing purposes */ - IntBuffer pixelBuffer = mPixelBuffer; - if (mUpdated && pixelBuffer != null) { - synchronized (pixelBuffer) { - pixelBuffer.position(0); - GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(), - (int)mScreenContext.viewport.height(), GLES20.GL_RGBA, - GLES20.GL_UNSIGNED_BYTE, pixelBuffer); - pixelBuffer.notify(); - } - } - } - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java deleted file mode 100644 index a3c04fa600f2..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/LayerView.java +++ /dev/null @@ -1,230 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoInputConnection; -import org.mozilla.gecko.gfx.FloatSize; -import org.mozilla.gecko.gfx.InputConnectionHandler; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.ui.SimpleScaleGestureDetector; -import android.content.Context; -import android.opengl.GLSurfaceView; -import android.view.View; -import android.view.GestureDetector; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.ScaleGestureDetector; -import android.widget.RelativeLayout; -import android.util.Log; -import java.nio.IntBuffer; -import java.util.LinkedList; - -/** - * A view rendered by the layer compositor. - * - * This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a - * mediator between the LayerRenderer and the LayerController. - */ -public class LayerView extends FlexibleGLSurfaceView { - private Context mContext; - private LayerController mController; - private InputConnectionHandler mInputConnectionHandler; - private LayerRenderer mRenderer; - private GestureDetector mGestureDetector; - private SimpleScaleGestureDetector mScaleGestureDetector; - private long mRenderTime; - private boolean mRenderTimeReset; - private static String LOGTAG = "GeckoLayerView"; - /* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */ - private LinkedList mEventQueue = new LinkedList(); - - - public LayerView(Context context, LayerController controller) { - super(context); - - mContext = context; - mController = controller; - mRenderer = new LayerRenderer(this); - setRenderer(mRenderer); - mGestureDetector = new GestureDetector(context, controller.getGestureListener()); - mScaleGestureDetector = - new SimpleScaleGestureDetector(controller.getScaleGestureListener()); - mGestureDetector.setOnDoubleTapListener(controller.getDoubleTapListener()); - mInputConnectionHandler = null; - - setFocusable(true); - setFocusableInTouchMode(true); - - createGLThread(); - } - - private void addToEventQueue(MotionEvent event) { - MotionEvent copy = MotionEvent.obtain(event); - mEventQueue.add(copy); - } - - public void processEventQueue() { - MotionEvent event = mEventQueue.poll(); - while(event != null) { - processEvent(event); - event = mEventQueue.poll(); - } - } - - public void clearEventQueue() { - mEventQueue.clear(); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - if (mController.onTouchEvent(event)) { - addToEventQueue(event); - return true; - } - return processEvent(event); - } - - private boolean processEvent(MotionEvent event) { - if (mGestureDetector.onTouchEvent(event)) - return true; - mScaleGestureDetector.onTouchEvent(event); - if (mScaleGestureDetector.isInProgress()) - return true; - mController.getPanZoomController().onTouchEvent(event); - return true; - } - - public LayerController getController() { return mController; } - - /** The LayerRenderer calls this to indicate that the window has changed size. */ - public void setViewportSize(IntSize size) { - mController.setViewportSize(new FloatSize(size)); - } - - //public GeckoInputConnection setInputConnectionHandler() { - // GeckoInputConnection geckoInputConnection = GeckoInputConnection.create(this); - // mInputConnectionHandler = geckoInputConnection; - // return geckoInputConnection; - //} - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onCreateInputConnection(outAttrs); - return null; - } - - @Override - public boolean onKeyPreIme(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onKeyPreIme(keyCode, event); - return false; - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onKeyDown(keyCode, event); - return false; - } - - @Override - public boolean onKeyLongPress(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onKeyLongPress(keyCode, event); - return false; - } - - @Override - public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onKeyMultiple(keyCode, repeatCount, event); - return false; - } - - @Override - public boolean onKeyUp(int keyCode, KeyEvent event) { - if (mInputConnectionHandler != null) - return mInputConnectionHandler.onKeyUp(keyCode, event); - return false; - } - - @Override - public void requestRender() { - super.requestRender(); - - synchronized(this) { - if (!mRenderTimeReset) { - mRenderTimeReset = true; - mRenderTime = System.nanoTime(); - } - } - } - - public void addLayer(Layer layer) { - mRenderer.addLayer(layer); - } - - public void removeLayer(Layer layer) { - mRenderer.removeLayer(layer); - } - - /** - * Returns the time elapsed between the first call of requestRender() after - * the last call of getRenderTime(), in nanoseconds. - */ - public long getRenderTime() { - synchronized(this) { - mRenderTimeReset = false; - return System.nanoTime() - mRenderTime; - } - } - - public int getMaxTextureSize() { - return mRenderer.getMaxTextureSize(); - } - - /** Used by robocop for testing purposes. Not for production use! This is called via reflection by robocop. */ - public IntBuffer getPixels() { - return mRenderer.getPixels(); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java deleted file mode 100644 index a958a54eb303..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/MultiTileLayer.java +++ /dev/null @@ -1,250 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- -* ***** BEGIN LICENSE BLOCK ***** -* Version: MPL 1.1/GPL 2.0/LGPL 2.1 -* -* The contents of this file are subject to the Mozilla Public License Version -* 1.1 (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* http://www.mozilla.org/MPL/ -* -* Software distributed under the License is distributed on an "AS IS" basis, -* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -* for the specific language governing rights and limitations under the -* License. -* -* The Original Code is Mozilla Android code. -* -* The Initial Developer of the Original Code is Mozilla Foundation. -* Portions created by the Initial Developer are Copyright (C) 2011-2012 -* the Initial Developer. All Rights Reserved. -* -* Contributor(s): -* Chris Lord -* Arkady Blyakher -* -* Alternatively, the contents of this file may be used under the terms of -* either the GNU General Public License Version 2 or later (the "GPL"), or -* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -* in which case the provisions of the GPL or the LGPL are applicable instead -* of those above. If you wish to allow use of your version of this file only -* under the terms of either the GPL or the LGPL, and not to allow others to -* use your version of this file under the terms of the MPL, indicate your -* decision by deleting the provisions above and replace them with the notice -* and other provisions required by the GPL or the LGPL. If you do not delete -* the provisions above, a recipient may use your version of this file under -* the terms of any one of the MPL, the GPL or the LGPL. -* -* ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Bitmap; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; -import android.util.Log; - -import org.libreoffice.LOKitShell; - -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.util.ArrayList; - -/** - * Encapsulates the logic needed to draw a layer made of multiple tiles. - *

- * TODO: Support repeating. - */ -public class MultiTileLayer extends Layer { - private static final String LOGTAG = "GeckoMultiTileLayer"; - - private final ArrayList mTiles; - private IntSize mTileSize; - private IntSize mSize; - - public MultiTileLayer(IntSize tileSize) { - super(); - mTileSize = tileSize; - mTiles = new ArrayList(); - mSize = new IntSize(0,0); - } - - public void invalidate(Rect dirtyRect) { - if (!inTransaction()) { - throw new RuntimeException("invalidate() is only valid inside a transaction"); - } - - for (SubTile layer : mTiles) { - IntSize tileSize = layer.getSize(); - Rect tileRect = new Rect(layer.x, layer.y, layer.x + tileSize.width, layer.y + tileSize.height); - - if (tileRect.intersect(dirtyRect)) { - tileRect.offset(-layer.x, -layer.y); - layer.invalidate(tileRect); - } - } - } - - public void invalidate() { - for (SubTile layer : mTiles) { - layer.invalidate(); - } - } - - public void setSize(IntSize size) { - mSize = size; - } - - @Override - public IntSize getSize() { - return mSize; - } - - private void validateTiles() { - Log.i(LOGTAG, "validateTiles()"); - - // Set tile origins and resolution - refreshTileMetrics(getOrigin(), getResolution(), false); - } - - @Override - protected boolean performUpdates(RenderContext context) { - super.performUpdates(context); - - validateTiles(); - - // Iterate over the tiles and decide which ones we'll be drawing - int dirtyTiles = 0; - boolean screenUpdateDone = false; - SubTile firstDirtyTile = null; - for (SubTile layer : mTiles) { - // First do a non-texture update to make sure coordinates are - // up-to-date. - boolean invalid = layer.getSkipTextureUpdate(); - layer.setSkipTextureUpdate(true); - layer.performUpdates(context); - - RectF layerBounds = layer.getBounds(context, new FloatSize(layer.getSize())); - boolean isDirty = layer.isDirty(); - - if (isDirty) { - if (!RectF.intersects(layerBounds, context.viewport)) { - if (firstDirtyTile == null) - firstDirtyTile = layer; - dirtyTiles++; - invalid = true; - } else { - // This tile intersects with the screen and is dirty, - // update it immediately. - layer.setSkipTextureUpdate(false); - screenUpdateDone = true; - layer.performUpdates(context); - invalid = false; - } - } - - // We use the SkipTextureUpdate flag as a marker of a tile's - // validity. This is required, as sometimes layers are drawn - // without updating first, and we mustn't draw tiles that have - // been marked as invalid that we haven't updated. - layer.setSkipTextureUpdate(invalid); - } - - // Now if no tiles that intersect with the screen were updated, update - // a single tile that doesn't (if there are any). This has the effect - // of spreading out non-critical texture upload over time, and smoothing - // upload-related hitches. - if (!screenUpdateDone && firstDirtyTile != null) { - firstDirtyTile.setSkipTextureUpdate(false); - firstDirtyTile.performUpdates(context); - dirtyTiles--; - } - - return (dirtyTiles == 0); - } - - private void refreshTileMetrics(Point origin, float resolution, boolean inTransaction) { - IntSize size = getSize(); - for (SubTile layer : mTiles) { - if (!inTransaction) { - layer.beginTransaction(); - } - - if (origin != null) { - layer.setOrigin(new Point(origin.x + layer.x, origin.y + layer.y)); - } - if (resolution >= 0.0f) { - layer.setResolution(resolution); - } - - if (!inTransaction) { - layer.endTransaction(); - } - } - } - - @Override - public void setOrigin(Point newOrigin) { - super.setOrigin(newOrigin); - refreshTileMetrics(newOrigin, -1, true); - } - - @Override - public void setResolution(float newResolution) { - super.setResolution(newResolution); - refreshTileMetrics(null, newResolution, true); - } - - @Override - public void beginTransaction() { - super.beginTransaction(); - - for (SubTile layer : mTiles) { - layer.beginTransaction(); - } - } - - @Override - public void endTransaction() { - for (SubTile layer : mTiles) { - layer.endTransaction(); - } - - super.endTransaction(); - } - - @Override - public void draw(RenderContext context) { - for (SubTile layer : mTiles) { - // We use the SkipTextureUpdate flag as a validity flag. If it's false, - // the contents of this tile are invalid and we shouldn't draw it. - if (layer.getSkipTextureUpdate()) - continue; - - // Avoid work, only draw tiles that intersect with the viewport - RectF layerBounds = layer.getBounds(context, new FloatSize(layer.getSize())); - if (RectF.intersects(layerBounds, context.viewport)) - layer.draw(context); - } - } - - @Override - public Region getValidRegion(RenderContext context) { - Region validRegion = new Region(); - for (SubTile tile : mTiles) { - if (tile.getSkipTextureUpdate()) - continue; - validRegion.op(tile.getValidRegion(context), Region.Op.UNION); - } - - return validRegion; - } - - public void addTile(Bitmap bitmap, int x, int y) { - SubTile tile = new SubTile(new BufferedCairoImage(bitmap), x,y); - tile.beginTransaction(); - mTiles.add(tile); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java deleted file mode 100644 index f139b202c7b5..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/NinePatchTileLayer.java +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.gfx.FloatSize; -import android.graphics.PointF; -import android.graphics.RectF; -import android.opengl.GLES11; -import android.opengl.GLES11Ext; -import android.util.Log; -import javax.microedition.khronos.opengles.GL10; -import java.nio.FloatBuffer; - -/** - * Encapsulates the logic needed to draw a nine-patch bitmap using OpenGL ES. - * - * For more information on nine-patch bitmaps, see the following document: - * http://developer.android.com/guide/topics/graphics/2d-graphics.html#nine-patch - */ -public class NinePatchTileLayer extends TileLayer { - private static final int PATCH_SIZE = 16; - private static final int TEXTURE_SIZE = 48; - - public NinePatchTileLayer(CairoImage image) { - super(false, image); - } - - @Override - public void draw(RenderContext context) { - if (!initialized()) - return; - - GLES11.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); - GLES11.glEnable(GL10.GL_BLEND); - try { - GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID()); - drawPatches(context); - } finally { - GLES11.glDisable(GL10.GL_BLEND); - } - } - - private void drawPatches(RenderContext context) { - /* - * We divide the nine-patch bitmap up as follows: - * - * +---+---+---+ - * | 0 | 1 | 2 | - * +---+---+---+ - * | 3 | | 4 | - * +---+---+---+ - * | 5 | 6 | 7 | - * +---+---+---+ - */ - - FloatSize size = context.pageSize; - float width = size.width, height = size.height; - - drawPatch(context, 0, 0, /* 0 */ - 0.0f, 0.0f, PATCH_SIZE, PATCH_SIZE); - drawPatch(context, PATCH_SIZE, 0, /* 1 */ - PATCH_SIZE, 0.0f, width, PATCH_SIZE); - drawPatch(context, PATCH_SIZE * 2, 0, /* 2 */ - PATCH_SIZE + width, 0.0f, PATCH_SIZE, PATCH_SIZE); - drawPatch(context, 0, PATCH_SIZE, /* 3 */ - 0.0f, PATCH_SIZE, PATCH_SIZE, height); - drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE, /* 4 */ - PATCH_SIZE + width, PATCH_SIZE, PATCH_SIZE, height); - drawPatch(context, 0, PATCH_SIZE * 2, /* 5 */ - 0.0f, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE); - drawPatch(context, PATCH_SIZE, PATCH_SIZE * 2, /* 6 */ - PATCH_SIZE, PATCH_SIZE + height, width, PATCH_SIZE); - drawPatch(context, PATCH_SIZE * 2, PATCH_SIZE * 2, /* 7 */ - PATCH_SIZE + width, PATCH_SIZE + height, PATCH_SIZE, PATCH_SIZE); - } - - private void drawPatch(RenderContext context, int textureX, int textureY, float tileX, - float tileY, float tileWidth, float tileHeight) { - int[] cropRect = { textureX, textureY + PATCH_SIZE, PATCH_SIZE, -PATCH_SIZE }; - GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, - 0); - - RectF viewport = context.viewport; - float viewportHeight = viewport.height(); - float drawX = tileX - viewport.left - PATCH_SIZE; - float drawY = viewportHeight - (tileY + tileHeight - viewport.top - PATCH_SIZE); - GLES11Ext.glDrawTexfOES(drawX, drawY, 0.0f, tileWidth, tileHeight); - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java deleted file mode 100644 index c9414ac8ecf0..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PanningPerfAPI.java +++ /dev/null @@ -1,125 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kartikaya Gupta - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import java.util.ArrayList; -import java.util.List; -import android.os.SystemClock; -import android.util.Log; - -public class PanningPerfAPI { - private static final String LOGTAG = "GeckoPanningPerfAPI"; - - // make this large enough to avoid having to resize the frame time - // list, as that may be expensive and impact the thing we're trying - // to measure. - private static final int EXPECTED_FRAME_COUNT = 2048; - - private static boolean mRecordingFrames = false; - private static List mFrameTimes; - private static long mFrameStartTime; - - private static boolean mRecordingCheckerboard = false; - private static List mCheckerboardAmounts; - private static long mCheckerboardStartTime; - - public static void startFrameTimeRecording() { - if (mRecordingFrames) { - Log.e(LOGTAG, "Error: startFrameTimeRecording() called while already recording!"); - return; - } - mRecordingFrames = true; - if (mFrameTimes == null) { - mFrameTimes = new ArrayList(EXPECTED_FRAME_COUNT); - } else { - mFrameTimes.clear(); - } - mFrameStartTime = SystemClock.uptimeMillis(); - } - - public static List stopFrameTimeRecording() { - if (!mRecordingFrames) { - Log.e(LOGTAG, "Error: stopFrameTimeRecording() called when not recording!"); - return null; - } - mRecordingFrames = false; - return mFrameTimes; - } - - public static void recordFrameTime() { - // this will be called often, so try to make it as quick as possible - if (mRecordingFrames) { - mFrameTimes.add(SystemClock.uptimeMillis() - mFrameStartTime); - } - } - - public static boolean isRecordingCheckerboard() { - return mRecordingCheckerboard; - } - - public static void startCheckerboardRecording() { - if (mRecordingCheckerboard) { - Log.e(LOGTAG, "Error: startCheckerboardRecording() called while already recording!"); - return; - } - mRecordingCheckerboard = true; - if (mCheckerboardAmounts == null) { - mCheckerboardAmounts = new ArrayList(EXPECTED_FRAME_COUNT); - } else { - mCheckerboardAmounts.clear(); - } - mCheckerboardStartTime = SystemClock.uptimeMillis(); - } - - public static List stopCheckerboardRecording() { - if (!mRecordingCheckerboard) { - Log.e(LOGTAG, "Error: stopCheckerboardRecording() called when not recording!"); - return null; - } - mRecordingCheckerboard = false; - return mCheckerboardAmounts; - } - - public static void recordCheckerboard(float amount) { - // this will be called often, so try to make it as quick as possible - if (mRecordingCheckerboard) { - mCheckerboardAmounts.add(amount); - } - } -} \ No newline at end of file diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java deleted file mode 100644 index bff9f9f345a1..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/PointUtils.java +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kartikaya Gupta - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Point; -import android.graphics.PointF; -import android.util.FloatMath; - -import org.json.JSONObject; -import org.json.JSONException; -import org.mozilla.gecko.util.FloatUtils; - -import java.lang.Math; - -public final class PointUtils { - public static PointF add(PointF one, PointF two) { - return new PointF(one.x + two.x, one.y + two.y); - } - - public static PointF subtract(PointF one, PointF two) { - return new PointF(one.x - two.x, one.y - two.y); - } - - public static PointF scale(PointF point, float factor) { - return new PointF(point.x * factor, point.y * factor); - } - - public static Point round(PointF point) { - return new Point(Math.round(point.x), Math.round(point.y)); - } - - /* Returns a new point that is a linear interpolation between start and end points. weight conrols the weighting - * of each of the original points (weight = 1 returns endPoint, weight = 0 returns startPoint) - */ - public static PointF interpolate(PointF startPoint, PointF endPoint, float weight) { - float x = FloatUtils.interpolate(startPoint.x, endPoint.x, weight); - float y = FloatUtils.interpolate(startPoint.y, endPoint.y, weight); - return new PointF(x, y); - } - - /* Computes the magnitude of the given vector. */ - public static float distance(PointF point) { - return (float)Math.sqrt(point.x * point.x + point.y * point.y); - } - - /** Computes the scalar distance between two points. */ - public static float distance(PointF one, PointF two) { - return PointF.length(one.x - two.x, one.y - two.y); - } - - public static JSONObject toJSON(PointF point) throws JSONException { - // Ensure we put ints, not longs, because Gecko message handlers call getInt(). - int x = Math.round(point.x); - int y = Math.round(point.y); - JSONObject json = new JSONObject(); - json.put("x", x); - json.put("y", y); - return json; - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java deleted file mode 100644 index 9a5049781c45..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/RectUtils.java +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kartikaya Gupta - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.util.FloatUtils; -import android.graphics.Point; -import android.graphics.PointF; -import android.graphics.Rect; -import android.graphics.RectF; -import org.json.JSONException; -import org.json.JSONObject; - -public final class RectUtils { - public static Rect create(JSONObject json) { - try { - int x = json.getInt("x"); - int y = json.getInt("y"); - int width = json.getInt("width"); - int height = json.getInt("height"); - return new Rect(x, y, x + width, y + height); - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - - public static Rect contract(Rect rect, int lessWidth, int lessHeight) { - float halfLessWidth = lessWidth / 2.0f; - float halfLessHeight = lessHeight / 2.0f; - return new Rect(Math.round(rect.left + halfLessWidth), - Math.round(rect.top + halfLessHeight), - Math.round(rect.right - halfLessWidth), - Math.round(rect.bottom - halfLessHeight)); - } - - public static RectF contract(RectF rect, float lessWidth, float lessHeight) { - float halfLessWidth = lessWidth / 2; - float halfLessHeight = lessHeight / 2; - return new RectF(rect.left + halfLessWidth, - rect.top + halfLessHeight, - rect.right - halfLessWidth, - rect.bottom - halfLessHeight); - } - - public static RectF expand(RectF rect, float moreWidth, float moreHeight) { - float halfMoreWidth = moreWidth / 2; - float halfMoreHeight = moreHeight / 2; - return new RectF(rect.left - halfMoreWidth, - rect.top - halfMoreHeight, - rect.right + halfMoreWidth, - rect.bottom + halfMoreHeight); - } - - public static RectF intersect(RectF one, RectF two) { - float left = Math.max(one.left, two.left); - float top = Math.max(one.top, two.top); - float right = Math.min(one.right, two.right); - float bottom = Math.min(one.bottom, two.bottom); - return new RectF(left, top, Math.max(right, left), Math.max(bottom, top)); - } - - public static RectF scale(RectF rect, float scale) { - float x = rect.left * scale; - float y = rect.top * scale; - return new RectF(x, y, - x + (rect.width() * scale), - y + (rect.height() * scale)); - } - - /** Returns the nearest integer rect of the given rect. */ - public static Rect round(RectF rect) { - return new Rect(Math.round(rect.left), Math.round(rect.top), - Math.round(rect.right), Math.round(rect.bottom)); - } - - public static IntSize getSize(Rect rect) { - return new IntSize(rect.width(), rect.height()); - } - - public static Point getOrigin(Rect rect) { - return new Point(rect.left, rect.top); - } - - public static PointF getOrigin(RectF rect) { - return new PointF(rect.left, rect.top); - } - - /* - * Returns the rect that represents a linear transition between `from` and `to` at time `t`, - * which is on the scale [0, 1). - */ - public static RectF interpolate(RectF from, RectF to, float t) { - return new RectF(FloatUtils.interpolate(from.left, to.left, t), - FloatUtils.interpolate(from.top, to.top, t), - FloatUtils.interpolate(from.right, to.right, t), - FloatUtils.interpolate(from.bottom, to.bottom, t)); - } - - public static boolean fuzzyEquals(RectF a, RectF b) { - return FloatUtils.fuzzyEquals(a.top, b.top) - && FloatUtils.fuzzyEquals(a.left, b.left) - && FloatUtils.fuzzyEquals(a.right, b.right) - && FloatUtils.fuzzyEquals(a.bottom, b.bottom); - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java deleted file mode 100644 index 68b7265b368b..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ScrollbarLayer.java +++ /dev/null @@ -1,425 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2011 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kartikaya Gupta - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.RectF; -import android.opengl.GLES20; - -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.util.FloatUtils; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -/** - * Draws a small rect. This is scaled to become a scrollbar. - */ -public class ScrollbarLayer extends TileLayer { - public static final long FADE_DELAY = 500; // milliseconds before fade-out starts - private static final float FADE_AMOUNT = 0.03f; // how much (as a percent) the scrollbar should fade per frame - - private static final int PADDING = 1; // gap between scrollbar and edge of viewport - private static final int BAR_SIZE = 6; - private static final int CAP_RADIUS = (BAR_SIZE / 2); - // Dimensions of the texture image - private static final float TEX_HEIGHT = 8.0f; - private static final float TEX_WIDTH = 8.0f; - // Texture coordinates for the scrollbar's body - // We take a 1x1 pixel from the center of the image and scale it to become the bar - private static final float[] BODY_TEX_COORDS = { - // x, y - CAP_RADIUS / TEX_WIDTH, CAP_RADIUS / TEX_HEIGHT, - CAP_RADIUS / TEX_WIDTH, (CAP_RADIUS + 1) / TEX_HEIGHT, - (CAP_RADIUS + 1) / TEX_WIDTH, CAP_RADIUS / TEX_HEIGHT, - (CAP_RADIUS + 1) / TEX_WIDTH, (CAP_RADIUS + 1) / TEX_HEIGHT - }; - // Texture coordinates for the top cap of the scrollbar - private static final float[] TOP_CAP_TEX_COORDS = { - // x, y - 0, 1.0f - CAP_RADIUS / TEX_HEIGHT, - 0, 1.0f, - BAR_SIZE / TEX_WIDTH, 1.0f - CAP_RADIUS / TEX_HEIGHT, - BAR_SIZE / TEX_WIDTH, 1.0f - }; - // Texture coordinates for the bottom cap of the scrollbar - private static final float[] BOT_CAP_TEX_COORDS = { - // x, y - 0, 1.0f - BAR_SIZE / TEX_HEIGHT, - 0, 1.0f - CAP_RADIUS / TEX_HEIGHT, - BAR_SIZE / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT, - BAR_SIZE / TEX_WIDTH, 1.0f - CAP_RADIUS / TEX_HEIGHT - }; - // Texture coordinates for the left cap of the scrollbar - private static final float[] LEFT_CAP_TEX_COORDS = { - // x, y - 0, 1.0f - BAR_SIZE / TEX_HEIGHT, - 0, 1.0f, - CAP_RADIUS / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT, - CAP_RADIUS / TEX_WIDTH, 1.0f - }; - // Texture coordinates for the right cap of the scrollbar - private static final float[] RIGHT_CAP_TEX_COORDS = { - // x, y - CAP_RADIUS / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT, - CAP_RADIUS / TEX_WIDTH, 1.0f, - BAR_SIZE / TEX_WIDTH, 1.0f - BAR_SIZE / TEX_HEIGHT, - BAR_SIZE / TEX_WIDTH, 1.0f - }; - private final boolean mVertical; - private final ByteBuffer mBuffer; - private final Bitmap mBitmap; - private final Canvas mCanvas; - private float mOpacity; - private boolean mFinalized = false; - - private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) { - super(false, image); - mVertical = vertical; - mBuffer = buffer; - - IntSize size = image.getSize(); - mBitmap = Bitmap.createBitmap(size.width, size.height, Bitmap.Config.ARGB_8888); - mCanvas = new Canvas(mBitmap); - } - - public static ScrollbarLayer create(boolean vertical) { - // just create an empty image for now, it will get drawn - // on demand anyway - int imageSize = IntSize.nextPowerOfTwo(BAR_SIZE); - ByteBuffer buffer = LOKitShell.allocateDirectBuffer(imageSize * imageSize * 4); - CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, - CairoImage.FORMAT_ARGB32); - return new ScrollbarLayer(image, vertical, buffer); - } - - protected void finalize() throws Throwable { - try { - if (!mFinalized && mBuffer != null) - LOKitShell.freeDirectBuffer(mBuffer); - mFinalized = true; - } finally { - super.finalize(); - } - } - - /** - * Decrease the opacity of the scrollbar by one frame's worth. - * Return true if the opacity was decreased, or false if the scrollbars - * are already fully faded out. - */ - public boolean fade() { - if (FloatUtils.fuzzyEquals(mOpacity, 0.0f)) { - return false; - } - beginTransaction(); - try { - setOpacity(Math.max(mOpacity - FADE_AMOUNT, 0.0f)); - invalidate(); - } finally { - endTransaction(); - } - return true; - } - - /** - * Restore the opacity of the scrollbar to fully opaque. - * Return true if the opacity was changed, or false if the scrollbars - * are already fully opaque. - */ - public boolean unfade() { - if (FloatUtils.fuzzyEquals(mOpacity, 1.0f)) { - return false; - } - beginTransaction(); - try { - setOpacity(1.0f); - invalidate(); - } finally { - endTransaction(); - } - return true; - } - - private void setOpacity(float opacity) { - mOpacity = opacity; - - Paint foregroundPaint = new Paint(); - foregroundPaint.setAntiAlias(true); - foregroundPaint.setStyle(Paint.Style.FILL); - // use a (a,r,g,b) color of (127,0,0,0), and multiply the alpha by mOpacity for fading - foregroundPaint.setColor(Color.argb(Math.round(mOpacity * 127), 0, 0, 0)); - - mCanvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR); - mCanvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint); - - mBitmap.copyPixelsToBuffer(mBuffer.asIntBuffer()); - } - - @Override - public void draw(RenderContext context) { - if (!initialized()) - return; - - try { - GLES20.glEnable(GLES20.GL_BLEND); - GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); - - Rect rect = RectUtils.round(mVertical - ? getVerticalRect(context) - : getHorizontalRect(context)); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID()); - - float viewWidth = context.viewport.width(); - float viewHeight = context.viewport.height(); - - float top = viewHeight - rect.top; - float bot = viewHeight - rect.bottom; - - // Coordinates for the scrollbar's body combined with the texture coordinates - float[] bodyCoords = { - // x, y, z, texture_x, texture_y - rect.left / viewWidth, bot / viewHeight, 0, - BODY_TEX_COORDS[0], BODY_TEX_COORDS[1], - - rect.left / viewWidth, (bot + rect.height()) / viewHeight, 0, - BODY_TEX_COORDS[2], BODY_TEX_COORDS[3], - - (rect.left + rect.width()) / viewWidth, bot / viewHeight, 0, - BODY_TEX_COORDS[4], BODY_TEX_COORDS[5], - - (rect.left + rect.width()) / viewWidth, (bot + rect.height()) / viewHeight, 0, - BODY_TEX_COORDS[6], BODY_TEX_COORDS[7] - }; - - // Get the buffer and handles from the context - FloatBuffer coordBuffer = context.coordBuffer; - int positionHandle = context.positionHandle; - int textureHandle = context.textureHandle; - - // Make sure we are at position zero in the buffer in case other draw methods did not - // clean up after themselves - coordBuffer.position(0); - coordBuffer.put(bodyCoords); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture coordinates. - coordBuffer.position(0); - - if (mVertical) { - // top endcap - float[] topCap = { - // x, y, z, texture_x, texture_y - rect.left / viewWidth, top / viewHeight, 0, - TOP_CAP_TEX_COORDS[0], TOP_CAP_TEX_COORDS[1], - - rect.left / viewWidth, (top + CAP_RADIUS) / viewHeight, 0, - TOP_CAP_TEX_COORDS[2], TOP_CAP_TEX_COORDS[3], - - (rect.left + BAR_SIZE) / viewWidth, top / viewHeight, 0, - TOP_CAP_TEX_COORDS[4], TOP_CAP_TEX_COORDS[5], - - (rect.left + BAR_SIZE) / viewWidth, (top + CAP_RADIUS) / viewHeight, 0, - TOP_CAP_TEX_COORDS[6], TOP_CAP_TEX_COORDS[7] - }; - - coordBuffer.put(topCap); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the - // buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture - // coordinates. - coordBuffer.position(0); - - // bottom endcap - float[] botCap = { - // x, y, z, texture_x, texture_y - rect.left / viewWidth, (bot - CAP_RADIUS) / viewHeight, 0, - BOT_CAP_TEX_COORDS[0], BOT_CAP_TEX_COORDS[1], - - rect.left / viewWidth, (bot) / viewHeight, 0, - BOT_CAP_TEX_COORDS[2], BOT_CAP_TEX_COORDS[3], - - (rect.left + BAR_SIZE) / viewWidth, (bot - CAP_RADIUS) / viewHeight, 0, - BOT_CAP_TEX_COORDS[4], BOT_CAP_TEX_COORDS[5], - - (rect.left + BAR_SIZE) / viewWidth, (bot) / viewHeight, 0, - BOT_CAP_TEX_COORDS[6], BOT_CAP_TEX_COORDS[7] - }; - - coordBuffer.put(botCap); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the - // buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture - // coordinates. - coordBuffer.position(0); - } else { - // left endcap - float[] leftCap = { - // x, y, z, texture_x, texture_y - (rect.left - CAP_RADIUS) / viewWidth, bot / viewHeight, 0, - LEFT_CAP_TEX_COORDS[0], LEFT_CAP_TEX_COORDS[1], - (rect.left - CAP_RADIUS) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0, - LEFT_CAP_TEX_COORDS[2], LEFT_CAP_TEX_COORDS[3], - (rect.left) / viewWidth, bot / viewHeight, 0, LEFT_CAP_TEX_COORDS[4], - LEFT_CAP_TEX_COORDS[5], - (rect.left) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0, - LEFT_CAP_TEX_COORDS[6], LEFT_CAP_TEX_COORDS[7] - }; - - coordBuffer.put(leftCap); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the - // buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - // Reset the position in the buffer for the next set of vertex and texture - // coordinates. - coordBuffer.position(0); - - // right endcap - float[] rightCap = { - // x, y, z, texture_x, texture_y - rect.right / viewWidth, (bot) / viewHeight, 0, - RIGHT_CAP_TEX_COORDS[0], RIGHT_CAP_TEX_COORDS[1], - - rect.right / viewWidth, (bot + BAR_SIZE) / viewHeight, 0, - RIGHT_CAP_TEX_COORDS[2], RIGHT_CAP_TEX_COORDS[3], - - (rect.right + CAP_RADIUS) / viewWidth, (bot) / viewHeight, 0, - RIGHT_CAP_TEX_COORDS[4], RIGHT_CAP_TEX_COORDS[5], - - (rect.right + CAP_RADIUS) / viewWidth, (bot + BAR_SIZE) / viewHeight, 0, - RIGHT_CAP_TEX_COORDS[6], RIGHT_CAP_TEX_COORDS[7] - }; - - coordBuffer.put(rightCap); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the - // buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, - coordBuffer); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - } - } finally { - GLES20.glDisable(GLES20.GL_BLEND); - } - } - - private RectF getVerticalRect(RenderContext context) { - RectF viewport = context.viewport; - FloatSize pageSize = context.pageSize; - float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS; - float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS; - if (barStart > barEnd) { - float middle = (barStart + barEnd) / 2.0f; - barStart = barEnd = middle; - } - float right = viewport.width() - PADDING; - return new RectF(right - BAR_SIZE, barStart, right, barEnd); - } - - private RectF getHorizontalRect(RenderContext context) { - RectF viewport = context.viewport; - FloatSize pageSize = context.pageSize; - float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS; - float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS; - if (barStart > barEnd) { - float middle = (barStart + barEnd) / 2.0f; - barStart = barEnd = middle; - } - float bottom = viewport.height() - PADDING; - return new RectF(barStart, bottom - BAR_SIZE, barEnd, bottom); - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java deleted file mode 100644 index d18579e1a117..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SingleTileLayer.java +++ /dev/null @@ -1,127 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.CairoUtils; -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.TileLayer; -import android.graphics.PointF; -import android.graphics.RectF; -import android.opengl.GLES20; -import android.util.Log; -import java.nio.FloatBuffer; -import javax.microedition.khronos.opengles.GL10; - -/** - * Encapsulates the logic needed to draw a single textured tile. - * - * TODO: Repeating textures really should be their own type of layer. - */ -public class SingleTileLayer extends TileLayer { - public SingleTileLayer(CairoImage image) { this(false, image); } - - public SingleTileLayer(boolean repeat, CairoImage image) { - super(repeat, image); - } - - @Override - public void draw(RenderContext context) { - // mTextureIDs may be null here during startup if Layer.java's draw method - // failed to acquire the transaction lock and call performUpdates. - if (!initialized()) - return; - - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, getTextureID()); - - RectF bounds; - int[] cropRect; - IntSize size = getSize(); - RectF viewport = context.viewport; - - if (repeats()) { - bounds = new RectF(0.0f, 0.0f, viewport.width(), viewport.height()); - int width = Math.round(viewport.width()); - int height = Math.round(viewport.height()); - cropRect = new int[] { 0, 0, width, height }; - } else { - bounds = getBounds(context, new FloatSize(size)); - cropRect = new int[] { 0, 0, size.width, size.height }; - } - - float height = bounds.height(); - float left = bounds.left - viewport.left; - float top = viewport.height() - (bounds.top + height - viewport.top); - - float[] coords = { - //x, y, z, texture_x, texture_y - left/viewport.width(), top/viewport.height(), 0, - cropRect[0]/(float)size.width, cropRect[1]/(float)size.height, - - left/viewport.width(), (top+height)/viewport.height(), 0, - cropRect[0]/(float)size.width, cropRect[3]/(float)size.height, - - (left+bounds.width())/viewport.width(), top/viewport.height(), 0, - cropRect[2]/(float)size.width, cropRect[1]/(float)size.height, - - (left+bounds.width())/viewport.width(), (top+height)/viewport.height(), 0, - cropRect[2]/(float)size.width, cropRect[3]/(float)size.height - }; - - FloatBuffer coordBuffer = context.coordBuffer; - int positionHandle = context.positionHandle; - int textureHandle = context.textureHandle; - - // Make sure we are at position zero in the buffer in case other draw methods did not clean - // up after themselves - coordBuffer.position(0); - coordBuffer.put(coords); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java deleted file mode 100644 index 0c40c3c1b7df..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/SubTile.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.mozilla.gecko.gfx; - -/** -* Created by quikee on 29.6.2014. -*/ -public class SubTile extends SingleTileLayer { - public int x; - public int y; - - public SubTile(CairoImage mImage, int mX, int mY) { - super(mImage); - x = mX; - y = mY; - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java deleted file mode 100644 index f2cc640baaa7..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextLayer.java +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -//import org.mozilla.gecko.GeckoAppShell; -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.gfx.BufferedCairoImage; -import org.mozilla.gecko.gfx.CairoImage; -import org.mozilla.gecko.gfx.IntSize; -import org.mozilla.gecko.gfx.SingleTileLayer; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Typeface; -import android.util.Log; -import java.nio.ByteBuffer; -import java.nio.IntBuffer; - -/** - * Draws text on a layer. This is used for the frame rate meter. - */ -public class TextLayer extends SingleTileLayer { - private final ByteBuffer mBuffer; - private final IntSize mSize; - private boolean mFinalized = false; - - /* - * This awkward pattern is necessary due to Java's restrictions on when one can call superclass - * constructors. - */ - private TextLayer(ByteBuffer buffer, BufferedCairoImage image, IntSize size, String text) { - super(false, image); - mBuffer = buffer; - mSize = size; - renderText(text); - } - - protected void finalize() throws Throwable { - try { - if (!mFinalized && mBuffer != null) - /*GeckoAppShell*/ LOKitShell.freeDirectBuffer(mBuffer); - mFinalized = true; - } finally { - super.finalize(); - } - } - - public static TextLayer create(IntSize size, String text) { - ByteBuffer buffer = /*GeckoAppShell*/LOKitShell.allocateDirectBuffer(size.width * size.height * 4); - BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height, - CairoImage.FORMAT_ARGB32); - return new TextLayer(buffer, image, size, text); - } - - public void setText(String text) { - renderText(text); - invalidate(); - } - - private void renderText(String text) { - Bitmap bitmap = Bitmap.createBitmap(mSize.width, mSize.height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - - Paint textPaint = new Paint(); - textPaint.setAntiAlias(true); - textPaint.setColor(Color.WHITE); - textPaint.setFakeBoldText(true); - textPaint.setTextSize(18.0f); - textPaint.setTypeface(Typeface.DEFAULT_BOLD); - float width = textPaint.measureText(text) + 18.0f; - - Paint backgroundPaint = new Paint(); - backgroundPaint.setColor(Color.argb(127, 0, 0, 0)); - canvas.drawRect(0.0f, 0.0f, width, 18.0f + 6.0f, backgroundPaint); - - canvas.drawText(text, 6.0f, 18.0f, textPaint); - - bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer()); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java deleted file mode 100644 index 4392c55e1ae7..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureGenerator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * James Willcox - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.opengl.GLES10; -import java.util.Stack; - -public class TextureGenerator { - private static final int MIN_TEXTURES = 5; - - private static TextureGenerator sSharedInstance; - private Stack mTextureIds; - - private TextureGenerator() { mTextureIds = new Stack(); } - - public static TextureGenerator get() { - if (sSharedInstance == null) - sSharedInstance = new TextureGenerator(); - return sSharedInstance; - } - - public synchronized int take() { - if (mTextureIds.empty()) - return 0; - - return (int)mTextureIds.pop(); - } - - public synchronized void fill() { - int[] textures = new int[1]; - while (mTextureIds.size() < MIN_TEXTURES) { - GLES10.glGenTextures(1, textures, 0); - mTextureIds.push(textures[0]); - } - } -} - - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java deleted file mode 100644 index e18139cb9bc9..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TextureReaper.java +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.opengl.GLES20; -import java.util.ArrayList; - -/** Manages a list of dead tiles, so we don't leak resources. */ -public class TextureReaper { - private static TextureReaper sSharedInstance; - private ArrayList mDeadTextureIDs; - - private TextureReaper() { mDeadTextureIDs = new ArrayList(); } - - public static TextureReaper get() { - if (sSharedInstance == null) - sSharedInstance = new TextureReaper(); - return sSharedInstance; - } - - public void add(int[] textureIDs) { - for (int textureID : textureIDs) - add(textureID); - } - - public void add(int textureID) { - mDeadTextureIDs.add(textureID); - } - - public void reap() { - int[] deadTextureIDs = new int[mDeadTextureIDs.size()]; - for (int i = 0; i < deadTextureIDs.length; i++) - deadTextureIDs[i] = mDeadTextureIDs.get(i); - mDeadTextureIDs.clear(); - - GLES20.glDeleteTextures(deadTextureIDs.length, deadTextureIDs, 0); - } -} - - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java deleted file mode 100644 index 64ec94dc694a..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/TileLayer.java +++ /dev/null @@ -1,256 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.Region; -import android.opengl.GLES20; -import android.util.Log; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -/** - * Base class for tile layers, which encapsulate the logic needed to draw textured tiles in OpenGL - * ES. - */ -public abstract class TileLayer extends Layer { - private static final String LOGTAG = "GeckoTileLayer"; - - private final Rect mDirtyRect; - private final CairoImage mImage; - private final boolean mRepeat; - private IntSize mSize; - private boolean mSkipTextureUpdate; - private int[] mTextureIDs; - - public TileLayer(boolean repeat, CairoImage image) { - mRepeat = repeat; - mImage = image; - mSize = new IntSize(0, 0); - mSkipTextureUpdate = false; - - IntSize bufferSize = mImage.getSize(); - mDirtyRect = new Rect(); - } - - @Override - public IntSize getSize() { return mImage.getSize(); } - - protected boolean repeats() { return mRepeat; } - protected int getTextureID() { return mTextureIDs[0]; } - protected boolean initialized() { return mImage != null && mTextureIDs != null; } - - @Override - protected void finalize() throws Throwable { - if (mTextureIDs != null) - TextureReaper.get().add(mTextureIDs); - } - - /** - * Invalidates the given rect so that it will be uploaded again. Only valid inside a - * transaction. - */ - public void invalidate(Rect rect) { - if (!inTransaction()) - throw new RuntimeException("invalidate() is only valid inside a transaction"); - mDirtyRect.union(rect); - } - - public void invalidate() { - IntSize bufferSize = mImage.getSize(); - invalidate(new Rect(0, 0, bufferSize.width, bufferSize.height)); - } - - public boolean isDirty() { - return mImage.getSize().isPositive() && (mTextureIDs == null || !mDirtyRect.isEmpty()); - } - - private void validateTexture() { - /* Calculate the ideal texture size. This must be a power of two if - * the texture is repeated or OpenGL ES 2.0 isn't supported, as - * OpenGL ES 2.0 is required for NPOT texture support (without - * extensions), but doesn't support repeating NPOT textures. - * - * XXX Currently, we don't pick a GLES 2.0 context, so always round. - */ - IntSize bufferSize = mImage.getSize(); - IntSize textureSize = bufferSize; - - textureSize = bufferSize.nextPowerOfTwo(); - - if (!textureSize.equals(mSize)) { - mSize = textureSize; - - // Delete the old texture - if (mTextureIDs != null) { - TextureReaper.get().add(mTextureIDs); - mTextureIDs = null; - - // Free the texture immediately, so we don't incur a - // temporarily increased memory usage. - TextureReaper.get().reap(); - } - } - } - - /** Tells the tile not to update the texture on the next update. */ - public void setSkipTextureUpdate(boolean skip) { - mSkipTextureUpdate = skip; - } - - public boolean getSkipTextureUpdate() { - return mSkipTextureUpdate; - } - - @Override - protected boolean performUpdates(RenderContext context) { - super.performUpdates(context); - - if (mSkipTextureUpdate) { - return false; - } - - // Reallocate the texture if the size has changed - validateTexture(); - - // Don't do any work if the image has an invalid size. - if (!mImage.getSize().isPositive()) - return true; - - // If we haven't allocated a texture, assume the whole region is dirty - if (mTextureIDs == null) { - uploadFullTexture(); - } else { - uploadDirtyRect(mDirtyRect); - } - - mDirtyRect.setEmpty(); - - return true; - } - - private void uploadFullTexture() { - IntSize bufferSize = mImage.getSize(); - uploadDirtyRect(new Rect(0, 0, bufferSize.width, bufferSize.height)); - } - - private void uploadDirtyRect(Rect dirtyRect) { - // If we have nothing to upload, just return for now - if (dirtyRect.isEmpty()) - return; - - // It's possible that the buffer will be null, check for that and return - ByteBuffer imageBuffer = mImage.getBuffer(); - if (imageBuffer == null) - return; - - boolean newlyCreated = false; - - if (mTextureIDs == null) { - mTextureIDs = new int[1]; - GLES20.glGenTextures(mTextureIDs.length, mTextureIDs, 0); - newlyCreated = true; - } - - IntSize bufferSize = mImage.getSize(); - Rect bufferRect = new Rect(0, 0, bufferSize.width, bufferSize.height); - - int cairoFormat = mImage.getFormat(); - CairoGLInfo glInfo = new CairoGLInfo(cairoFormat); - - bindAndSetGLParameters(); - - if (newlyCreated || dirtyRect.contains(bufferRect)) { - if (mSize.equals(bufferSize)) { - GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, - mSize.height, 0, glInfo.format, glInfo.type, imageBuffer); - return; - } else { - GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, glInfo.internalFormat, mSize.width, - mSize.height, 0, glInfo.format, glInfo.type, null); - GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, 0, bufferSize.width, - bufferSize.height, glInfo.format, glInfo.type, imageBuffer); - return; - } - } - - // Make sure that the dirty region intersects with the buffer rect, - // otherwise we'll end up with an invalid buffer pointer. - if (!Rect.intersects(dirtyRect, bufferRect)) { - return; - } - - /* - * Upload the changed rect. We have to widen to the full width of the texture - * because we can't count on the device having support for GL_EXT_unpack_subimage, - * and going line-by-line is too slow. - * - * XXX We should still use GL_EXT_unpack_subimage when available. - */ - Buffer viewBuffer = imageBuffer.slice(); - int bpp = CairoUtils.bitsPerPixelForCairoFormat(cairoFormat) / 8; - int position = dirtyRect.top * bufferSize.width * bpp; - if (position > viewBuffer.limit()) { - Log.e(LOGTAG, "### Position outside tile! " + dirtyRect.top); - return; - } - - viewBuffer.position(position); - GLES20.glTexSubImage2D(GLES20.GL_TEXTURE_2D, 0, 0, dirtyRect.top, bufferSize.width, - Math.min(bufferSize.height - dirtyRect.top, dirtyRect.height()), - glInfo.format, glInfo.type, viewBuffer); - } - - private void bindAndSetGLParameters() { - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, - GLES20.GL_NEAREST); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, - GLES20.GL_LINEAR); - - int repeatMode = mRepeat ? GLES20.GL_REPEAT : GLES20.GL_CLAMP_TO_EDGE; - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, repeatMode); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, repeatMode); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java deleted file mode 100644 index 9f443ea52894..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewTransform.java +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -public class ViewTransform { - public float x; - public float y; - public float scale; - - public ViewTransform(float inX, float inY, float inScale) { - x = inX; - y = inY; - scale = inScale; - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java deleted file mode 100644 index d98b47421520..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/ViewportMetrics.java +++ /dev/null @@ -1,306 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.DisplayMetrics; - -import org.json.JSONException; -import org.json.JSONObject; -import org.libreoffice.LibreOfficeMainActivity; -import org.mozilla.gecko.util.FloatUtils; - -/** - * ViewportMetrics manages state and contains some utility functions related to - * the page viewport for the Gecko layer client to use. - */ -public class ViewportMetrics { - private static final String LOGTAG = "GeckoViewportMetrics"; - private static final float MAX_BIAS = 0.8f; - private FloatSize mPageSize; - private RectF mViewportRect; - private PointF mViewportOffset; - private float mZoomFactor; - // A scale from -1,-1 to 1,1 that represents what edge of the displayport - // we want the viewport to be biased towards. - private PointF mViewportBias; - - public ViewportMetrics() { - DisplayMetrics metrics = new DisplayMetrics(); - LibreOfficeMainActivity.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - - mPageSize = new FloatSize(metrics.widthPixels, metrics.heightPixels); - mViewportRect = new RectF(0, 0, metrics.widthPixels, metrics.heightPixels); - mViewportOffset = new PointF(0, 0); - mZoomFactor = 1.0f; - mViewportBias = new PointF(0.0f, 0.0f); - } - - public ViewportMetrics(ViewportMetrics viewport) { - mPageSize = new FloatSize(viewport.getPageSize()); - mViewportRect = new RectF(viewport.getViewport()); - PointF offset = viewport.getViewportOffset(); - mViewportOffset = new PointF(offset.x, offset.y); - mZoomFactor = viewport.getZoomFactor(); - mViewportBias = viewport.mViewportBias; - } - - public ViewportMetrics(JSONObject json) throws JSONException { - float x = (float) json.getDouble("x"); - float y = (float) json.getDouble("y"); - float width = (float) json.getDouble("width"); - float height = (float) json.getDouble("height"); - float pageWidth = (float) json.getDouble("pageWidth"); - float pageHeight = (float) json.getDouble("pageHeight"); - float offsetX = (float) json.getDouble("offsetX"); - float offsetY = (float) json.getDouble("offsetY"); - float zoom = (float) json.getDouble("zoom"); - - mPageSize = new FloatSize(pageWidth, pageHeight); - mViewportRect = new RectF(x, y, x + width, y + height); - mViewportOffset = new PointF(offsetX, offsetY); - mZoomFactor = zoom; - mViewportBias = new PointF(0.0f, 0.0f); - } - - public PointF getOptimumViewportOffset(IntSize displayportSize) { - /* XXX Until bug #524925 is fixed, changing the viewport origin will - * cause unnecessary relayouts. This may cause rendering time to - * increase and should be considered. - */ - RectF viewport = getClampedViewport(); - - FloatSize bufferSpace = new FloatSize(displayportSize.width - viewport.width(), - displayportSize.height - viewport.height()); - PointF optimumOffset = - new PointF(bufferSpace.width * ((mViewportBias.x + 1.0f) / 2.0f), - bufferSpace.height * ((mViewportBias.y + 1.0f) / 2.0f)); - - // Make sure this offset won't cause wasted pixels in the displayport - // (i.e. make sure the resultant displayport intersects with the page - // as much as possible) - if (viewport.left - optimumOffset.x < 0) - optimumOffset.x = viewport.left; - else if ((bufferSpace.width - optimumOffset.x) + viewport.right > mPageSize.width) - optimumOffset.x = bufferSpace.width - (mPageSize.width - viewport.right); - - if (viewport.top - optimumOffset.y < 0) - optimumOffset.y = viewport.top; - else if ((bufferSpace.height - optimumOffset.y) + viewport.bottom > mPageSize.height) - optimumOffset.y = bufferSpace.height - (mPageSize.height - viewport.bottom); - - return new PointF(Math.round(optimumOffset.x), Math.round(optimumOffset.y)); - } - - public PointF getOrigin() { - return new PointF(mViewportRect.left, mViewportRect.top); - } - - public void setOrigin(PointF origin) { - // When the origin is set, we compare it with the last value set and - // change the viewport bias accordingly, so that any viewport based - // on these metrics will have a larger buffer in the direction of - // movement. - - // XXX Note the comment about bug #524925 in getOptimumViewportOffset. - // Ideally, the viewport bias would be a sliding scale, but we - // don't want to change it too often at the moment. - if (FloatUtils.fuzzyEquals(origin.x, mViewportRect.left)) - mViewportBias.x = 0; - else - mViewportBias.x = ((mViewportRect.left - origin.x) > 0) ? MAX_BIAS : -MAX_BIAS; - if (FloatUtils.fuzzyEquals(origin.y, mViewportRect.top)) - mViewportBias.y = 0; - else - mViewportBias.y = ((mViewportRect.top - origin.y) > 0) ? MAX_BIAS : -MAX_BIAS; - - mViewportRect.set(origin.x, origin.y, - origin.x + mViewportRect.width(), - origin.y + mViewportRect.height()); - } - - public PointF getDisplayportOrigin() { - return new PointF(mViewportRect.left - mViewportOffset.x, - mViewportRect.top - mViewportOffset.y); - } - - public FloatSize getSize() { - return new FloatSize(mViewportRect.width(), mViewportRect.height()); - } - - public void setSize(FloatSize size) { - mViewportRect.right = mViewportRect.left + size.width; - mViewportRect.bottom = mViewportRect.top + size.height; - } - - public RectF getViewport() { - return mViewportRect; - } - - public void setViewport(RectF viewport) { - mViewportRect = viewport; - } - - /** - * Returns the viewport rectangle, clamped within the page-size. - */ - public RectF getClampedViewport() { - RectF clampedViewport = new RectF(mViewportRect); - - // While the viewport size ought to never exceed the page size, we - // do the clamping in this order to make sure that the origin is - // never negative. - if (clampedViewport.right > mPageSize.width) - clampedViewport.offset(mPageSize.width - clampedViewport.right, 0); - if (clampedViewport.left < 0) - clampedViewport.offset(-clampedViewport.left, 0); - - if (clampedViewport.bottom > mPageSize.height) - clampedViewport.offset(0, mPageSize.height - clampedViewport.bottom); - if (clampedViewport.top < 0) - clampedViewport.offset(0, -clampedViewport.top); - - return clampedViewport; - } - - public PointF getViewportOffset() { - return mViewportOffset; - } - - public void setViewportOffset(PointF offset) { - mViewportOffset = offset; - } - - public FloatSize getPageSize() { - return mPageSize; - } - - public void setPageSize(FloatSize pageSize) { - mPageSize = pageSize; - } - - public float getZoomFactor() { - return mZoomFactor; - } - - public void setZoomFactor(float zoomFactor) { - mZoomFactor = zoomFactor; - } - - /* This will set the zoom factor and re-scale page-size and viewport offset - * accordingly. The given focus will remain at the same point on the screen - * after scaling. - */ - public void scaleTo(float newZoomFactor, PointF focus) { - float scaleFactor = newZoomFactor / mZoomFactor; - - mPageSize = mPageSize.scale(scaleFactor); - - PointF origin = getOrigin(); - origin.offset(focus.x, focus.y); - origin = PointUtils.scale(origin, scaleFactor); - origin.offset(-focus.x, -focus.y); - setOrigin(origin); - - mZoomFactor = newZoomFactor; - - // Similar to setOrigin, set the viewport bias based on the focal point - // of the zoom so that a viewport based on these metrics will have a - // larger buffer based on the direction of movement when scaling. - // - // This is biased towards scaling outwards, as zooming in doesn't - // really require a viewport bias. - mViewportBias.set(((focus.x / mViewportRect.width()) * (2.0f * MAX_BIAS)) - MAX_BIAS, - ((focus.y / mViewportRect.height()) * (2.0f * MAX_BIAS)) - MAX_BIAS); - } - - /* - * Returns the viewport metrics that represent a linear transition between `from` and `to` at - * time `t`, which is on the scale [0, 1). This function interpolates the viewport rect, the - * page size, the offset, and the zoom factor. - */ - public ViewportMetrics interpolate(ViewportMetrics to, float t) { - ViewportMetrics result = new ViewportMetrics(); - result.mPageSize = mPageSize.interpolate(to.mPageSize, t); - result.mZoomFactor = FloatUtils.interpolate(mZoomFactor, to.mZoomFactor, t); - result.mViewportRect = RectUtils.interpolate(mViewportRect, to.mViewportRect, t); - result.mViewportOffset = PointUtils.interpolate(mViewportOffset, to.mViewportOffset, t); - return result; - } - - public boolean fuzzyEquals(ViewportMetrics other) { - return mPageSize.fuzzyEquals(other.mPageSize) - && RectUtils.fuzzyEquals(mViewportRect, other.mViewportRect) - && FloatUtils.fuzzyEquals(mViewportOffset, other.mViewportOffset) - && FloatUtils.fuzzyEquals(mZoomFactor, other.mZoomFactor); - } - - public String toJSON() { - // Round off height and width. Since the height and width are the size of the screen, it - // makes no sense to send non-integer coordinates to Gecko. - int height = Math.round(mViewportRect.height()); - int width = Math.round(mViewportRect.width()); - - StringBuffer sb = new StringBuffer(256); - sb.append("{ \"x\" : ").append(mViewportRect.left) - .append(", \"y\" : ").append(mViewportRect.top) - .append(", \"width\" : ").append(width) - .append(", \"height\" : ").append(height) - .append(", \"pageWidth\" : ").append(mPageSize.width) - .append(", \"pageHeight\" : ").append(mPageSize.height) - .append(", \"offsetX\" : ").append(mViewportOffset.x) - .append(", \"offsetY\" : ").append(mViewportOffset.y) - .append(", \"zoom\" : ").append(mZoomFactor) - .append(" }"); - return sb.toString(); - } - - @Override - public String toString() { - StringBuffer buff = new StringBuffer(128); - buff.append("v=").append(mViewportRect.toString()) - .append(" p=").append(mPageSize.toString()) - .append(" z=").append(mZoomFactor) - .append(" o=").append(mViewportOffset.x) - .append(',').append(mViewportOffset.y); - return buff.toString(); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java deleted file mode 100644 index 0f314ae71620..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/VirtualLayer.java +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Chris Lord - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import android.graphics.Point; - -public class VirtualLayer extends Layer { - private Listener mListener; - private IntSize mSize; - - public void setListener(Listener listener) { - mListener = listener; - } - - @Override - public void draw(RenderContext context) { - // No-op. - } - - @Override - public IntSize getSize() { - return mSize; - } - - public void setSize(IntSize size) { - mSize = size; - } - - @Override - protected boolean performUpdates(RenderContext context) { - boolean dimensionsChanged = dimensionChangesPending(); - boolean result = super.performUpdates(context); - if (dimensionsChanged && mListener != null) { - mListener.dimensionsChanged(getOrigin(), getResolution()); - } - - return result; - } - - public interface Listener { - void dimensionsChanged(Point newOrigin, float newResolution); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java deleted file mode 100644 index b123d55c403d..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/gfx/WidgetTileLayer.java +++ /dev/null @@ -1,160 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2010 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * James Willcox - * Arkady Blyakher - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.gfx; - -import org.libreoffice.LOKitShell; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.SingleTileLayer; -//import org.mozilla.gecko.GeckoAppShell; -import android.graphics.RectF; -import android.util.Log; -import android.opengl.GLES20; -import java.nio.FloatBuffer; - -/** - * Encapsulates the logic needed to draw the single-tiled Gecko texture - */ -public class WidgetTileLayer extends Layer { - private static final String LOGTAG = "WidgetTileLayer"; - - private int[] mTextureIDs; - private CairoImage mImage; - - public WidgetTileLayer(CairoImage image) { - mImage = image; - } - - protected boolean initialized() { return mTextureIDs != null; } - - @Override - public IntSize getSize() { return mImage.getSize(); } - - protected void bindAndSetGLParameters() { - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); - GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - } - - @Override - protected void finalize() throws Throwable { - if (mTextureIDs != null) - TextureReaper.get().add(mTextureIDs); - } - - @Override - protected boolean performUpdates(RenderContext context) { - super.performUpdates(context); - - if (mTextureIDs == null) { - mTextureIDs = new int[1]; - GLES20.glGenTextures(1, mTextureIDs, 0); - } - - bindAndSetGLParameters(); - LOKitShell.bindWidgetTexture(); - - return true; - } - - @Override - public void draw(RenderContext context) { - // mTextureIDs may be null here during startup if Layer.java's draw method - // failed to acquire the transaction lock and call performUpdates. - if (!initialized()) - return; - - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureIDs[0]); - - RectF bounds; - int[] cropRect; - IntSize size = getSize(); - RectF viewport = context.viewport; - - bounds = getBounds(context, new FloatSize(size)); - cropRect = new int[] { 0, 0, size.width, size.height }; - bounds.offset(-viewport.left, -viewport.top); - - float top = viewport.height() - (bounds.top + bounds.height()); - - // There may be errors from a previous GL call, so clear them first because - // we want to check for one below - while (GLES20.glGetError() != GLES20.GL_NO_ERROR); - - float[] coords = { - //x, y, z, texture_x, texture_y - bounds.left/viewport.width(), top/viewport.height(), 0, - cropRect[0]/size.width, cropRect[1]/size.height, - - bounds.left/viewport.width(), (top+bounds.height())/viewport.height(), 0, - cropRect[0]/size.width, cropRect[3]/size.height, - - (bounds.left+bounds.width())/viewport.width(), top/viewport.height(), 0, - cropRect[2]/size.width, cropRect[1]/size.height, - - (bounds.left+bounds.width())/viewport.width(), (top+bounds.height())/viewport.height(), - 0, - cropRect[2]/size.width, cropRect[3]/size.height - }; - - // Get the buffer and handles from the context - FloatBuffer coordBuffer = context.coordBuffer; - int positionHandle = context.positionHandle; - int textureHandle = context.textureHandle; - - // Make sure we are at position zero in the buffer in case other draw methods did not clean - // up after themselves - coordBuffer.position(0); - coordBuffer.put(coords); - - // Vertex coordinates are x,y,z starting at position 0 into the buffer. - coordBuffer.position(0); - GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false, 20, coordBuffer); - - // Texture coordinates are texture_x, texture_y starting at position 3 into the buffer. - coordBuffer.position(3); - GLES20.glVertexAttribPointer(textureHandle, 2, GLES20.GL_FLOAT, false, 20, coordBuffer); - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - int error = GLES20.glGetError(); - if (error != GLES20.GL_NO_ERROR) { - Log.i(LOGTAG, "Failed to draw texture: " + error); - } - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java deleted file mode 100644 index 8c0fce4c73b3..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/Axis.java +++ /dev/null @@ -1,271 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Kartikaya Gupta - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.ui; - -import org.mozilla.gecko.util.FloatUtils; - -/** - * This class represents the physics for one axis of movement (i.e. either - * horizontal or vertical). It tracks the different properties of movement - * like displacement, velocity, viewport dimensions, etc. pertaining to - * a particular axis. - */ -abstract class Axis { - // This fraction of velocity remains after every animation frame when the velocity is low. - private static final float FRICTION_SLOW = 0.85f; - // This fraction of velocity remains after every animation frame when the velocity is high. - private static final float FRICTION_FAST = 0.97f; - // Below this velocity (in pixels per frame), the friction starts increasing from FRICTION_FAST - // to FRICTION_SLOW. - private static final float VELOCITY_THRESHOLD = 10.0f; - // The maximum velocity change factor between events, per ms, in %. - // Direction changes are excluded. - private static final float MAX_EVENT_ACCELERATION = 0.012f; - - // The rate of deceleration when the surface has overscrolled. - private static final float OVERSCROLL_DECEL_RATE = 0.04f; - // The percentage of the surface which can be overscrolled before it must snap back. - private static final float SNAP_LIMIT = 0.75f; - - // The minimum amount of space that must be present for an axis to be considered scrollable, - // in pixels. - private static final float MIN_SCROLLABLE_DISTANCE = 0.5f; - // The number of milliseconds per frame assuming 60 fps - private static final float MS_PER_FRAME = 1000.0f / 60.0f; - - private enum FlingStates { - STOPPED, - PANNING, - FLINGING, - } - - private enum Overscroll { - NONE, - MINUS, // Overscrolled in the negative direction - PLUS, // Overscrolled in the positive direction - BOTH, // Overscrolled in both directions (page is zoomed to smaller than screen) - } - - private final SubdocumentScrollHelper mSubscroller; - - private float mFirstTouchPos; /* Position of the first touch event on the current drag. */ - private float mTouchPos; /* Position of the most recent touch event on the current drag. */ - private float mLastTouchPos; /* Position of the touch event before touchPos. */ - private float mVelocity; /* Velocity in this direction; pixels per animation frame. */ - public boolean mScrollingDisabled; /* Whether movement on this axis is locked. */ - private boolean mDisableSnap; /* Whether overscroll snapping is disabled. */ - private float mDisplacement; - - private FlingStates mFlingState; /* The fling state we're in on this axis. */ - - protected abstract float getOrigin(); - protected abstract float getViewportLength(); - protected abstract float getPageLength(); - - Axis(SubdocumentScrollHelper subscroller) { - mSubscroller = subscroller; - } - - private float getViewportEnd() { - return getOrigin() + getViewportLength(); - } - - void startTouch(float pos) { - mVelocity = 0.0f; - mScrollingDisabled = false; - mFirstTouchPos = mTouchPos = mLastTouchPos = pos; - } - - float panDistance(float currentPos) { - return currentPos - mFirstTouchPos; - } - - void setScrollingDisabled(boolean disabled) { - mScrollingDisabled = disabled; - } - - void saveTouchPos() { - mLastTouchPos = mTouchPos; - } - - void updateWithTouchAt(float pos, float timeDelta) { - float newVelocity = (mTouchPos - pos) / timeDelta * MS_PER_FRAME; - - // If there's a direction change, or current velocity is very low, - // allow setting of the velocity outright. Otherwise, use the current - // velocity and a maximum change factor to set the new velocity. - boolean curVelocityIsLow = Math.abs(mVelocity) < 1.0f; - boolean directionChange = (mVelocity > 0) != (newVelocity > 0); - if (curVelocityIsLow || (directionChange && !FloatUtils.fuzzyEquals(newVelocity, 0.0f))) { - mVelocity = newVelocity; - } else { - float maxChange = Math.abs(mVelocity * timeDelta * MAX_EVENT_ACCELERATION); - mVelocity = Math.min(mVelocity + maxChange, Math.max(mVelocity - maxChange, newVelocity)); - } - - mTouchPos = pos; - } - - boolean overscrolled() { - return getOverscroll() != Overscroll.NONE; - } - - private Overscroll getOverscroll() { - boolean minus = (getOrigin() < 0.0f); - boolean plus = (getViewportEnd() > getPageLength()); - if (minus && plus) { - return Overscroll.BOTH; - } else if (minus) { - return Overscroll.MINUS; - } else if (plus) { - return Overscroll.PLUS; - } else { - return Overscroll.NONE; - } - } - - // Returns the amount that the page has been overscrolled. If the page hasn't been - // overscrolled on this axis, returns 0. - private float getExcess() { - switch (getOverscroll()) { - case MINUS: return -getOrigin(); - case PLUS: return getViewportEnd() - getPageLength(); - case BOTH: return getViewportEnd() - getPageLength() - getOrigin(); - default: return 0.0f; - } - } - - /* - * Returns true if the page is zoomed in to some degree along this axis such that scrolling is - * possible and this axis has not been scroll locked while panning. Otherwise, returns false. - */ - private boolean scrollable() { - return getViewportLength() <= getPageLength() - MIN_SCROLLABLE_DISTANCE && - !mScrollingDisabled; - } - - /* - * Returns the resistance, as a multiplier, that should be taken into account when - * tracking or pinching. - */ - float getEdgeResistance() { - float excess = getExcess(); - if (excess > 0.0f) { - // excess can be greater than viewport length, but the resistance - // must never drop below 0.0 - return Math.max(0.0f, SNAP_LIMIT - excess / getViewportLength()); - } - return 1.0f; - } - - /* Returns the velocity. If the axis is locked, returns 0. */ - float getRealVelocity() { - return scrollable() ? mVelocity : 0f; - } - - void startPan() { - mFlingState = FlingStates.PANNING; - } - - void startFling(boolean stopped) { - mDisableSnap = mSubscroller.scrolling(); - - if (stopped) { - mFlingState = FlingStates.STOPPED; - } else { - mFlingState = FlingStates.FLINGING; - } - } - - /* Advances a fling animation by one step. */ - boolean advanceFling() { - if (mFlingState != FlingStates.FLINGING) { - return false; - } - if (mSubscroller.scrolling() && !mSubscroller.lastScrollSucceeded()) { - // if the subdocument stopped scrolling, it's because it reached the end - // of the subdocument. we don't do overscroll on subdocuments, so there's - // no point in continuing this fling. - return false; - } - - float excess = getExcess(); - if (mDisableSnap || FloatUtils.fuzzyEquals(excess, 0.0f)) { - // If we aren't overscrolled, just apply friction. - if (Math.abs(mVelocity) >= VELOCITY_THRESHOLD) { - mVelocity *= FRICTION_FAST; - } else { - float t = mVelocity / VELOCITY_THRESHOLD; - mVelocity *= FloatUtils.interpolate(FRICTION_SLOW, FRICTION_FAST, t); - } - } else { - // Otherwise, decrease the velocity linearly. - float elasticity = 1.0f - excess / (getViewportLength() * SNAP_LIMIT); - if (getOverscroll() == Overscroll.MINUS) { - mVelocity = Math.min((mVelocity + OVERSCROLL_DECEL_RATE) * elasticity, 0.0f); - } else { // must be Overscroll.PLUS - mVelocity = Math.max((mVelocity - OVERSCROLL_DECEL_RATE) * elasticity, 0.0f); - } - } - - return true; - } - - void stopFling() { - mVelocity = 0.0f; - mFlingState = FlingStates.STOPPED; - } - - // Performs displacement of the viewport position according to the current velocity. - void displace() { - if (!mSubscroller.scrolling() && !scrollable()) - return; - - if (mFlingState == FlingStates.PANNING) - mDisplacement += (mLastTouchPos - mTouchPos) * getEdgeResistance(); - else - mDisplacement += mVelocity; - } - - float resetDisplacement() { - float d = mDisplacement; - mDisplacement = 0.0f; - return d; - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java deleted file mode 100644 index c3cacccf805e..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/PanZoomController.java +++ /dev/null @@ -1,921 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2009-2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * Kartikaya Gupta - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.ui; - -import org.json.JSONObject; -import org.json.JSONException; -import org.libreoffice.LOKitShell; -import org.libreoffice.LibreOfficeMainActivity; -import org.mozilla.gecko.gfx.FloatSize; -import org.mozilla.gecko.gfx.LayerController; -import org.mozilla.gecko.gfx.PointUtils; -import org.mozilla.gecko.gfx.ViewportMetrics; -import org.mozilla.gecko.util.FloatUtils; -import org.mozilla.gecko.GeckoEventListener; -import android.graphics.PointF; -import android.graphics.RectF; -import android.util.FloatMath; -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; -import java.util.Timer; -import java.util.TimerTask; - -/* - * Handles the kinetic scrolling and zooming physics for a layer controller. - * - * Many ideas are from Joe Hewitt's Scrollability: - * https://github.com/joehewitt/scrollability/ - */ -public class PanZoomController - extends GestureDetector.SimpleOnGestureListener - implements SimpleScaleGestureDetector.SimpleScaleGestureListener, GeckoEventListener -{ - private static final String LOGTAG = "GeckoPanZoomController"; - - private static String MESSAGE_ZOOM_RECT = "Browser:ZoomToRect"; - private static String MESSAGE_ZOOM_PAGE = "Browser:ZoomToPageWidth"; - - // Animation stops if the velocity is below this value when overscrolled or panning. - private static final float STOPPED_THRESHOLD = 4.0f; - - // Animation stops is the velocity is below this threshold when flinging. - private static final float FLING_STOPPED_THRESHOLD = 0.1f; - - // The distance the user has to pan before we recognize it as such (e.g. to avoid 1-pixel pans - // between the touch-down and touch-up of a click). In units of density-independent pixels. - public static final float PAN_THRESHOLD = 1/16f * LOKitShell.getDpi(); - - // Angle from axis within which we stay axis-locked - private static final double AXIS_LOCK_ANGLE = Math.PI / 6.0; // 30 degrees - - // The maximum amount we allow you to zoom into a page - private static final float MAX_ZOOM = 4.0f; - - /* 16 precomputed frames of the _ease-out_ animation from the CSS Transitions specification. */ - private static final float[] EASE_OUT_ANIMATION_FRAMES = { - 0.00000f, /* 0 */ - 0.10211f, /* 1 */ - 0.19864f, /* 2 */ - 0.29043f, /* 3 */ - 0.37816f, /* 4 */ - 0.46155f, /* 5 */ - 0.54054f, /* 6 */ - 0.61496f, /* 7 */ - 0.68467f, /* 8 */ - 0.74910f, /* 9 */ - 0.80794f, /* 10 */ - 0.86069f, /* 11 */ - 0.90651f, /* 12 */ - 0.94471f, /* 13 */ - 0.97401f, /* 14 */ - 0.99309f, /* 15 */ - }; - - private enum PanZoomState { - NOTHING, /* no touch-start events received */ - FLING, /* all touches removed, but we're still scrolling page */ - TOUCHING, /* one touch-start event received */ - PANNING_LOCKED, /* touch-start followed by move (i.e. panning with axis lock) */ - PANNING, /* panning without axis lock */ - PANNING_HOLD, /* in panning, but not moving. - * similar to TOUCHING but after starting a pan */ - PANNING_HOLD_LOCKED, /* like PANNING_HOLD, but axis lock still in effect */ - PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */ - ANIMATED_ZOOM /* animated zoom to a new rect */ - } - - private final LayerController mController; - private final SubdocumentScrollHelper mSubscroller; - private final Axis mX; - private final Axis mY; - - private Thread mMainThread; - - /* The timer that handles flings or bounces. */ - private Timer mAnimationTimer; - /* The runnable being scheduled by the animation timer. */ - private AnimationRunnable mAnimationRunnable; - /* The zoom focus at the first zoom event (in page coordinates). */ - private PointF mLastZoomFocus; - /* The time the last motion event took place. */ - private long mLastEventTime; - /* Current state the pan/zoom UI is in. */ - private PanZoomState mState; - - public PanZoomController(LayerController controller) { - mController = controller; - mSubscroller = new SubdocumentScrollHelper(this); - mX = new AxisX(mSubscroller); - mY = new AxisY(mSubscroller); - - mMainThread = LibreOfficeMainActivity.mAppContext.getMainLooper().getThread(); - checkMainThread(); - - mState = PanZoomState.NOTHING; - - //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_RECT, this); - //GeckoAppShell.registerGeckoEventListener(MESSAGE_ZOOM_PAGE, this); - } - - // for debugging bug 713011; it can be taken out once that is resolved. - private void checkMainThread() { - if (mMainThread != Thread.currentThread()) { - // log with full stack trace - Log.e(LOGTAG, "Uh-oh, we're running on the wrong thread!", new Exception()); - } - } - - public void handleMessage(String event, JSONObject message) { - Log.i(LOGTAG, "Got message: " + event); - try { - if (MESSAGE_ZOOM_RECT.equals(event)) { - float x = (float)message.getDouble("x"); - float y = (float)message.getDouble("y"); - final RectF zoomRect = new RectF(x, y, - x + (float)message.getDouble("w"), - y + (float)message.getDouble("h")); - mController.post(new Runnable() { - public void run() { - animatedZoomTo(zoomRect); - } - }); - } else if (MESSAGE_ZOOM_PAGE.equals(event)) { - FloatSize pageSize = mController.getPageSize(); - - RectF viewableRect = mController.getViewport(); - float y = viewableRect.top; - // attempt to keep zoom keep focused on the center of the viewport - float newHeight = viewableRect.height() * pageSize.width / viewableRect.width(); - float dh = viewableRect.height() - newHeight; // increase in the height - final RectF r = new RectF(0.0f, - y + dh/2, - pageSize.width, - y + dh/2 + newHeight); - mController.post(new Runnable() { - public void run() { - animatedZoomTo(r); - } - }); - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e); - } - } - - public boolean onTouchEvent(MotionEvent event) { - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: return onTouchStart(event); - case MotionEvent.ACTION_MOVE: return onTouchMove(event); - case MotionEvent.ACTION_UP: return onTouchEnd(event); - case MotionEvent.ACTION_CANCEL: return onTouchCancel(event); - default: return false; - } - } - - /** This function must be called from the UI thread. */ - public void abortAnimation() { - checkMainThread(); - // this happens when gecko changes the viewport on us or if the device is rotated. - // if that's the case, abort any animation in progress and re-zoom so that the page - // snaps to edges. for other cases (where the user's finger(s) are down) don't do - // anything special. - switch (mState) { - case FLING: - mX.stopFling(); - mY.stopFling(); - mState = PanZoomState.NOTHING; - // fall through - case ANIMATED_ZOOM: - // the zoom that's in progress likely makes no sense any more (such as if - // the screen orientation changed) so abort it - // fall through - case NOTHING: - // Don't do animations here; they're distracting and can cause flashes on page - // transitions. - mController.setViewportMetrics(getValidViewportMetrics()); - mController.notifyLayerClientOfGeometryChange(); - break; - } - } - - /** This must be called on the UI thread. */ - public void pageSizeUpdated() { - if (mState == PanZoomState.NOTHING) { - ViewportMetrics validated = getValidViewportMetrics(); - if (! mController.getViewportMetrics().fuzzyEquals(validated)) { - // page size changed such that we are now in overscroll. snap to the - // the nearest valid viewport - mController.setViewportMetrics(validated); - mController.notifyLayerClientOfGeometryChange(); - } - } - } - - /* - * Panning/scrolling - */ - - private boolean onTouchStart(MotionEvent event) { - Log.d(LOGTAG, "onTouchStart in state " + mState); - // user is taking control of movement, so stop - // any auto-movement we have going - stopAnimationTimer(); - mSubscroller.cancel(); - - switch (mState) { - case ANIMATED_ZOOM: - return false; - case FLING: - case NOTHING: - startTouch(event.getX(0), event.getY(0), event.getEventTime()); - return false; - case TOUCHING: - case PANNING: - case PANNING_LOCKED: - case PANNING_HOLD: - case PANNING_HOLD_LOCKED: - case PINCHING: - Log.e(LOGTAG, "Received impossible touch down while in " + mState); - return false; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchStart"); - return false; - } - - private boolean onTouchMove(MotionEvent event) { - Log.d(LOGTAG, "onTouchMove in state " + mState); - - switch (mState) { - case NOTHING: - case FLING: - // should never happen - Log.e(LOGTAG, "Received impossible touch move while in " + mState); - return false; - - case TOUCHING: - if (panDistance(event) < PAN_THRESHOLD) { - return false; - } - cancelTouch(); - startPanning(event.getX(0), event.getY(0), event.getEventTime()); - //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */); - //GeckoApp.mAutoCompletePopup.hide(); - track(event); - return true; - - case PANNING_HOLD_LOCKED: - //GeckoApp.mAutoCompletePopup.hide(); - mState = PanZoomState.PANNING_LOCKED; - // fall through - case PANNING_LOCKED: - track(event); - return true; - - case PANNING_HOLD: - //GeckoApp.mAutoCompletePopup.hide(); - mState = PanZoomState.PANNING; - // fall through - case PANNING: - track(event); - return true; - - case ANIMATED_ZOOM: - case PINCHING: - // scale gesture listener will handle this - return false; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchMove"); - return false; - } - - private boolean onTouchEnd(MotionEvent event) { - Log.d(LOGTAG, "onTouchEnd in " + mState); - - switch (mState) { - case NOTHING: - case FLING: - // should never happen - Log.e(LOGTAG, "Received impossible touch end while in " + mState); - return false; - case TOUCHING: - mState = PanZoomState.NOTHING; - // the switch into TOUCHING might have happened while the page was - // snapping back after overscroll. we need to finish the snap if that - // was the case - bounce(); - return false; - case PANNING: - case PANNING_LOCKED: - case PANNING_HOLD: - case PANNING_HOLD_LOCKED: - mState = PanZoomState.FLING; - fling(); - return true; - case PINCHING: - mState = PanZoomState.NOTHING; - return true; - case ANIMATED_ZOOM: - return false; - } - Log.e(LOGTAG, "Unhandled case " + mState + " in onTouchEnd"); - return false; - } - - private boolean onTouchCancel(MotionEvent event) { - Log.d(LOGTAG, "onTouchCancel in " + mState); - - mState = PanZoomState.NOTHING; - // ensure we snap back if we're overscrolled - bounce(); - return false; - } - - private void startTouch(float x, float y, long time) { - mX.startTouch(x); - mY.startTouch(y); - mState = PanZoomState.TOUCHING; - mLastEventTime = time; - } - - private void startPanning(float x, float y, long time) { - float dx = mX.panDistance(x); - float dy = mY.panDistance(y); - double angle = Math.atan2(dy, dx); // range [-pi, pi] - angle = Math.abs(angle); // range [0, pi] - - // When the touch move breaks through the pan threshold, reposition the touch down origin - // so the page won't jump when we start panning. - mX.startTouch(x); - mY.startTouch(y); - mLastEventTime = time; - - if (angle < AXIS_LOCK_ANGLE || angle > (Math.PI - AXIS_LOCK_ANGLE)) { - mY.setScrollingDisabled(true); - mState = PanZoomState.PANNING_LOCKED; - } else if (Math.abs(angle - (Math.PI / 2)) < AXIS_LOCK_ANGLE) { - mX.setScrollingDisabled(true); - mState = PanZoomState.PANNING_LOCKED; - } else { - mState = PanZoomState.PANNING; - } - } - - private float panDistance(MotionEvent move) { - float dx = mX.panDistance(move.getX(0)); - float dy = mY.panDistance(move.getY(0)); - return FloatMath.sqrt(dx * dx + dy * dy); - } - - private void track(float x, float y, long time) { - float timeDelta = (float)(time - mLastEventTime); - if (FloatUtils.fuzzyEquals(timeDelta, 0)) { - // probably a duplicate event, ignore it. using a zero timeDelta will mess - // up our velocity - return; - } - mLastEventTime = time; - - mX.updateWithTouchAt(x, timeDelta); - mY.updateWithTouchAt(y, timeDelta); - } - - private void track(MotionEvent event) { - mX.saveTouchPos(); - mY.saveTouchPos(); - - for (int i = 0; i < event.getHistorySize(); i++) { - track(event.getHistoricalX(0, i), - event.getHistoricalY(0, i), - event.getHistoricalEventTime(i)); - } - track(event.getX(0), event.getY(0), event.getEventTime()); - - if (stopped()) { - if (mState == PanZoomState.PANNING) { - mState = PanZoomState.PANNING_HOLD; - } else if (mState == PanZoomState.PANNING_LOCKED) { - mState = PanZoomState.PANNING_HOLD_LOCKED; - } else { - // should never happen, but handle anyway for robustness - Log.e(LOGTAG, "Impossible case " + mState + " when stopped in track"); - mState = PanZoomState.PANNING_HOLD_LOCKED; - } - } - - mX.startPan(); - mY.startPan(); - updatePosition(); - } - - private void fling() { - updatePosition(); - - stopAnimationTimer(); - - boolean stopped = stopped(); - mX.startFling(stopped); - mY.startFling(stopped); - - startAnimationTimer(new FlingRunnable()); - } - - /* Performs a bounce-back animation to the given viewport metrics. */ - private void bounce(ViewportMetrics metrics) { - stopAnimationTimer(); - - ViewportMetrics bounceStartMetrics = new ViewportMetrics(mController.getViewportMetrics()); - if (bounceStartMetrics.fuzzyEquals(metrics)) { - mState = PanZoomState.NOTHING; - return; - } - - mState = PanZoomState.FLING; - Log.d(LOGTAG, "end bounce at " + metrics); - - startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics)); - } - - /* Performs a bounce-back animation to the nearest valid viewport metrics. */ - private void bounce() { - bounce(getValidViewportMetrics()); - } - - /* Starts the fling or bounce animation. */ - private void startAnimationTimer(final AnimationRunnable runnable) { - if (mAnimationTimer != null) { - Log.e(LOGTAG, "Attempted to start a new fling without canceling the old one!"); - stopAnimationTimer(); - } - - //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */); - - mAnimationTimer = new Timer("Animation Timer"); - mAnimationRunnable = runnable; - mAnimationTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { mController.post(runnable); } - }, 0, 1000L/60L); - } - - /* Stops the fling or bounce animation. */ - private void stopAnimationTimer() { - if (mAnimationTimer != null) { - mAnimationTimer.cancel(); - mAnimationTimer = null; - } - if (mAnimationRunnable != null) { - mAnimationRunnable.terminate(); - mAnimationRunnable = null; - } - - //GeckoApp.mAppContext.showPlugins(); - } - - private float getVelocity() { - float xvel = mX.getRealVelocity(); - float yvel = mY.getRealVelocity(); - return FloatMath.sqrt(xvel * xvel + yvel * yvel); - } - - private boolean stopped() { - return getVelocity() < STOPPED_THRESHOLD; - } - - PointF getDisplacement() { - return new PointF(mX.resetDisplacement(), mY.resetDisplacement()); - } - - private void updatePosition() { - mX.displace(); - mY.displace(); - PointF displacement = getDisplacement(); - if (! mSubscroller.scrollBy(displacement)) { - synchronized (mController) { - mController.scrollBy(displacement); - } - } - } - - private abstract class AnimationRunnable implements Runnable { - private boolean mAnimationTerminated; - - /* This should always run on the UI thread */ - public final void run() { - /* - * Since the animation timer queues this runnable on the UI thread, it - * is possible that even when the animation timer is cancelled, there - * are multiple instances of this queued, so we need to have another - * mechanism to abort. This is done by using the mAnimationTerminated flag. - */ - if (mAnimationTerminated) { - return; - } - animateFrame(); - } - - protected abstract void animateFrame(); - - /* This should always run on the UI thread */ - protected final void terminate() { - mAnimationTerminated = true; - } - } - - /* The callback that performs the bounce animation. */ - private class BounceRunnable extends AnimationRunnable { - /* The current frame of the bounce-back animation */ - private int mBounceFrame; - /* - * The viewport metrics that represent the start and end of the bounce-back animation, - * respectively. - */ - private ViewportMetrics mBounceStartMetrics; - private ViewportMetrics mBounceEndMetrics; - - BounceRunnable(ViewportMetrics startMetrics, ViewportMetrics endMetrics) { - mBounceStartMetrics = startMetrics; - mBounceEndMetrics = endMetrics; - } - - protected void animateFrame() { - /* - * The pan/zoom controller might have signaled to us that it wants to abort the - * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail - * out. - */ - if (mState != PanZoomState.FLING) { - finishAnimation(); - return; - } - - /* Perform the next frame of the bounce-back animation. */ - if (mBounceFrame < EASE_OUT_ANIMATION_FRAMES.length) { - advanceBounce(); - return; - } - - /* Finally, if there's nothing else to do, complete the animation and go to sleep. */ - finishBounce(); - finishAnimation(); - mState = PanZoomState.NOTHING; - } - - /* Performs one frame of a bounce animation. */ - private void advanceBounce() { - synchronized (mController) { - float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame]; - ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t); - mController.setViewportMetrics(newMetrics); - mController.notifyLayerClientOfGeometryChange(); - mBounceFrame++; - } - } - - /* Concludes a bounce animation and snaps the viewport into place. */ - private void finishBounce() { - synchronized (mController) { - mController.setViewportMetrics(mBounceEndMetrics); - mController.notifyLayerClientOfGeometryChange(); - mBounceFrame = -1; - } - } - } - - // The callback that performs the fling animation. - private class FlingRunnable extends AnimationRunnable { - protected void animateFrame() { - /* - * The pan/zoom controller might have signaled to us that it wants to abort the - * animation by setting the state to PanZoomState.NOTHING. Handle this case and bail - * out. - */ - if (mState != PanZoomState.FLING) { - finishAnimation(); - return; - } - - /* Advance flings, if necessary. */ - boolean flingingX = mX.advanceFling(); - boolean flingingY = mY.advanceFling(); - - boolean overscrolled = (mX.overscrolled() || mY.overscrolled()); - - /* If we're still flinging in any direction, update the origin. */ - if (flingingX || flingingY) { - updatePosition(); - - /* - * Check to see if we're still flinging with an appreciable velocity. The threshold is - * higher in the case of overscroll, so we bounce back eagerly when overscrolling but - * coast smoothly to a stop when not. In other words, require a greater velocity to - * maintain the fling once we enter overscroll. - */ - float threshold = (overscrolled && !mSubscroller.scrolling() ? STOPPED_THRESHOLD : FLING_STOPPED_THRESHOLD); - if (getVelocity() >= threshold) { - // we're still flinging - return; - } - - mX.stopFling(); - mY.stopFling(); - } - - /* Perform a bounce-back animation if overscrolled. */ - if (overscrolled) { - bounce(); - } else { - finishAnimation(); - mState = PanZoomState.NOTHING; - } - } - } - - private void finishAnimation() { - checkMainThread(); - - Log.d(LOGTAG, "Finishing animation at " + mController.getViewportMetrics()); - stopAnimationTimer(); - - // Force a viewport synchronisation - //GeckoApp.mAppContext.showPlugins(); - mController.setForceRedraw(); - mController.notifyLayerClientOfGeometryChange(); - } - - /* Returns the nearest viewport metrics with no overscroll visible. */ - private ViewportMetrics getValidViewportMetrics() { - return getValidViewportMetrics(new ViewportMetrics(mController.getViewportMetrics())); - } - - private ViewportMetrics getValidViewportMetrics(ViewportMetrics viewportMetrics) { - Log.d(LOGTAG, "generating valid viewport using " + viewportMetrics); - - /* First, we adjust the zoom factor so that we can make no overscrolled area visible. */ - float zoomFactor = viewportMetrics.getZoomFactor(); - FloatSize pageSize = viewportMetrics.getPageSize(); - RectF viewport = viewportMetrics.getViewport(); - - float focusX = viewport.width() / 2.0f; - float focusY = viewport.height() / 2.0f; - float minZoomFactor = 0.0f; - if (viewport.width() > pageSize.width && pageSize.width > 0) { - float scaleFactor = viewport.width() / pageSize.width; - minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor); - focusX = 0.0f; - } - if (viewport.height() > pageSize.height && pageSize.height > 0) { - float scaleFactor = viewport.height() / pageSize.height; - minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor); - focusY = 0.0f; - } - - if (!FloatUtils.fuzzyEquals(minZoomFactor, 0.0f)) { - // if one (or both) of the page dimensions is smaller than the viewport, - // zoom using the top/left as the focus on that axis. this prevents the - // scenario where, if both dimensions are smaller than the viewport, but - // by different scale factors, we end up scrolled to the end on one axis - // after applying the scale - PointF center = new PointF(focusX, focusY); - viewportMetrics.scaleTo(minZoomFactor, center); - } else if (zoomFactor > MAX_ZOOM) { - PointF center = new PointF(viewport.width() / 2.0f, viewport.height() / 2.0f); - viewportMetrics.scaleTo(MAX_ZOOM, center); - } - - /* Now we pan to the right origin. */ - viewportMetrics.setViewport(viewportMetrics.getClampedViewport()); - Log.d(LOGTAG, "generated valid viewport as " + viewportMetrics); - - return viewportMetrics; - } - - private class AxisX extends Axis { - AxisX(SubdocumentScrollHelper subscroller) { super(subscroller); } - @Override - public float getOrigin() { return mController.getOrigin().x; } - @Override - protected float getViewportLength() { return mController.getViewportSize().width; } - @Override - protected float getPageLength() { return mController.getPageSize().width; } - } - - private class AxisY extends Axis { - AxisY(SubdocumentScrollHelper subscroller) { super(subscroller); } - @Override - public float getOrigin() { return mController.getOrigin().y; } - @Override - protected float getViewportLength() { return mController.getViewportSize().height; } - @Override - protected float getPageLength() { return mController.getPageSize().height; } - } - - /* - * Zooming - */ - @Override - public boolean onScaleBegin(SimpleScaleGestureDetector detector) { - Log.d(LOGTAG, "onScaleBegin in " + mState); - - if (mState == PanZoomState.ANIMATED_ZOOM) - return false; - - mState = PanZoomState.PINCHING; - mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY()); - //GeckoApp.mAppContext.hidePlugins(false /* don't hide layers, only views */); - //GeckoApp.mAutoCompletePopup.hide(); - cancelTouch(); - - return true; - } - - @Override - public boolean onScale(SimpleScaleGestureDetector detector) { - Log.d(LOGTAG, "onScale in state " + mState); - - if (mState == PanZoomState.ANIMATED_ZOOM) - return false; - - float prevSpan = detector.getPreviousSpan(); - if (FloatUtils.fuzzyEquals(prevSpan, 0.0f)) { - // let's eat this one to avoid setting the new zoom to infinity (bug 711453) - return true; - } - - float spanRatio = detector.getCurrentSpan() / prevSpan; - - /* - * Apply edge resistance if we're zoomed out smaller than the page size by scaling the zoom - * factor toward 1.0. - */ - float resistance = Math.min(mX.getEdgeResistance(), mY.getEdgeResistance()); - if (spanRatio > 1.0f) - spanRatio = 1.0f + (spanRatio - 1.0f) * resistance; - else - spanRatio = 1.0f - (1.0f - spanRatio) * resistance; - - synchronized (mController) { - float newZoomFactor = mController.getZoomFactor() * spanRatio; - if (newZoomFactor >= MAX_ZOOM) { - // apply resistance when zooming past MAX_ZOOM, - // such that it asymptotically reaches MAX_ZOOM + 1.0 - // but never exceeds that - float excessZoom = newZoomFactor - MAX_ZOOM; - excessZoom = 1.0f - (float)Math.exp(-excessZoom); - newZoomFactor = MAX_ZOOM + excessZoom; - } - - mController.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(), - mLastZoomFocus.y - detector.getFocusY())); - PointF focus = new PointF(detector.getFocusX(), detector.getFocusY()); - mController.scaleWithFocus(newZoomFactor, focus); - } - - mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY()); - - return true; - } - - @Override - public void onScaleEnd(SimpleScaleGestureDetector detector) { - Log.d(LOGTAG, "onScaleEnd in " + mState); - - if (mState == PanZoomState.ANIMATED_ZOOM) - return; - - // switch back to the touching state - startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime()); - - // Force a viewport synchronisation - //GeckoApp.mAppContext.showPlugins(); - mController.setForceRedraw(); - mController.notifyLayerClientOfGeometryChange(); - } - - public boolean getRedrawHint() { - return (mState != PanZoomState.PINCHING && mState != PanZoomState.ANIMATED_ZOOM); - } - - private void sendPointToGecko(String event, MotionEvent motionEvent) { - String json; - try { - PointF point = new PointF(motionEvent.getX(), motionEvent.getY()); - point = mController.convertViewPointToLayerPoint(point); - if (point == null) { - return; - } - json = PointUtils.toJSON(point).toString(); - } catch (Exception e) { - Log.e(LOGTAG, "Unable to convert point to JSON for " + event, e); - return; - } - - //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(event, json)); - } - - @Override - public void onLongPress(MotionEvent motionEvent) { - sendPointToGecko("Gesture:LongPress", motionEvent); - } - - @Override - public boolean onDown(MotionEvent motionEvent) { - sendPointToGecko("Gesture:ShowPress", motionEvent); - return false; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent motionEvent) { - //GeckoApp.mAutoCompletePopup.hide(); - sendPointToGecko("Gesture:SingleTap", motionEvent); - return true; - } - - @Override - public boolean onDoubleTap(MotionEvent motionEvent) { - sendPointToGecko("Gesture:DoubleTap", motionEvent); - return true; - } - - public void cancelTouch() { - //GeckoEvent e = GeckoEvent.createBroadcastEvent("Gesture:CancelTouch", ""); - //GeckoAppShell.sendEventToGecko(e); - } - - private boolean animatedZoomTo(RectF zoomToRect) { - //GeckoApp.mAutoCompletePopup.hide(); - - mState = PanZoomState.ANIMATED_ZOOM; - final float startZoom = mController.getZoomFactor(); - - RectF viewport = mController.getViewport(); - // 1. adjust the aspect ratio of zoomToRect to match that of the current viewport, - // enlarging as necessary (if it gets too big, it will get shrunk in the next step). - // while enlarging make sure we enlarge equally on both sides to keep the target rect - // centered. - float targetRatio = viewport.width() / viewport.height(); - float rectRatio = zoomToRect.width() / zoomToRect.height(); - if (FloatUtils.fuzzyEquals(targetRatio, rectRatio)) { - // all good, do nothing - } else if (targetRatio < rectRatio) { - // need to increase zoomToRect height - float newHeight = zoomToRect.width() / targetRatio; - zoomToRect.top -= (newHeight - zoomToRect.height()) / 2; - zoomToRect.bottom = zoomToRect.top + newHeight; - } else { // targetRatio > rectRatio) { - // need to increase zoomToRect width - float newWidth = targetRatio * zoomToRect.height(); - zoomToRect.left -= (newWidth - zoomToRect.width()) / 2; - zoomToRect.right = zoomToRect.left + newWidth; - } - - float finalZoom = viewport.width() * startZoom / zoomToRect.width(); - - ViewportMetrics finalMetrics = new ViewportMetrics(mController.getViewportMetrics()); - finalMetrics.setOrigin(new PointF(zoomToRect.left, zoomToRect.top)); - finalMetrics.scaleTo(finalZoom, new PointF(0.0f, 0.0f)); - - // 2. now run getValidViewportMetrics on it, so that the target viewport is - // clamped down to prevent overscroll, over-zoom, and other bad conditions. - finalMetrics = getValidViewportMetrics(finalMetrics); - - bounce(finalMetrics); - return true; - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java deleted file mode 100644 index 4f9e39857e81..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SimpleScaleGestureDetector.java +++ /dev/null @@ -1,332 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Patrick Walton - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.ui; - -import org.mozilla.gecko.gfx.PointUtils; -import org.json.JSONException; -import android.graphics.PointF; -import android.util.Log; -import android.view.MotionEvent; -import java.util.LinkedList; -import java.util.ListIterator; -import java.util.Stack; - -/** - * A less buggy, and smoother, replacement for the built-in Android ScaleGestureDetector. - * - * This gesture detector is more reliable than the built-in ScaleGestureDetector because: - * - * - It doesn't assume that pointer IDs are numbered 0 and 1. - * - * - It doesn't attempt to correct for "slop" when resting one's hand on the device. On some - * devices (e.g. the Droid X) this can cause the ScaleGestureDetector to lose track of how many - * pointers are down, with disastrous results (bug 706684). - * - * - Cancelling a zoom into a pan is handled correctly. - * - * - Starting with three or more fingers down, releasing fingers so that only two are down, and - * then performing a scale gesture is handled correctly. - * - * - It doesn't take pressure into account, which results in smoother scaling. - */ -public class SimpleScaleGestureDetector { - private static final String LOGTAG = "GeckoSimpleScaleGestureDetector"; - - private SimpleScaleGestureListener mListener; - private long mLastEventTime; - - /* Information about all pointers that are down. */ - private LinkedList mPointerInfo; - - /** Creates a new gesture detector with the given listener. */ - public SimpleScaleGestureDetector(SimpleScaleGestureListener listener) { - mListener = listener; - mPointerInfo = new LinkedList(); - } - - /** Forward touch events to this function. */ - public void onTouchEvent(MotionEvent event) { - switch (event.getAction() & MotionEvent.ACTION_MASK) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_POINTER_DOWN: - onTouchStart(event); - break; - case MotionEvent.ACTION_MOVE: - onTouchMove(event); - break; - case MotionEvent.ACTION_POINTER_UP: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - onTouchEnd(event); - break; - } - } - - private int getPointersDown() { - return mPointerInfo.size(); - } - - private int getActionIndex(MotionEvent event) { - return (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) - >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; - } - - private void onTouchStart(MotionEvent event) { - mLastEventTime = event.getEventTime(); - mPointerInfo.addFirst(PointerInfo.create(event, getActionIndex(event))); - if (getPointersDown() == 2) { - sendScaleGesture(EventType.BEGIN); - } - } - - private void onTouchMove(MotionEvent event) { - mLastEventTime = event.getEventTime(); - for (int i = 0; i < event.getPointerCount(); i++) { - PointerInfo pointerInfo = pointerInfoForEventIndex(event, i); - if (pointerInfo != null) { - pointerInfo.populate(event, i); - } - } - - if (getPointersDown() == 2) { - sendScaleGesture(EventType.CONTINUE); - } - } - - private void onTouchEnd(MotionEvent event) { - mLastEventTime = event.getEventTime(); - - int id = event.getPointerId(getActionIndex(event)); - ListIterator iterator = mPointerInfo.listIterator(); - while (iterator.hasNext()) { - PointerInfo pointerInfo = iterator.next(); - if (pointerInfo.getId() != id) { - continue; - } - - // One of the pointers we were tracking was lifted. Remove its info object from the - // list, recycle it to avoid GC pauses, and send an onScaleEnd() notification if this - // ended the gesture. - iterator.remove(); - pointerInfo.recycle(); - if (getPointersDown() == 1) { - sendScaleGesture(EventType.END); - } - } - } - - /** - * Returns the X coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusX() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().x; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().x + pointerB.getCurrent().x) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusX()!"); - return 0.0f; - } - - /** - * Returns the Y coordinate of the focus location (the midpoint of the two fingers). If only - * one finger is down, returns the location of that finger. - */ - public float getFocusY() { - switch (getPointersDown()) { - case 1: - return mPointerInfo.getFirst().getCurrent().y; - case 2: - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return (pointerA.getCurrent().y + pointerB.getCurrent().y) / 2.0f; - } - - Log.e(LOGTAG, "No gesture taking place in getFocusY()!"); - return 0.0f; - } - - /** Returns the most recent distance between the two pointers. */ - public float getCurrentSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getCurrentSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - return PointUtils.distance(pointerA.getCurrent(), pointerB.getCurrent()); - } - - /** Returns the second most recent distance between the two pointers. */ - public float getPreviousSpan() { - if (getPointersDown() != 2) { - Log.e(LOGTAG, "No gesture taking place in getPreviousSpan()!"); - return 0.0f; - } - - PointerInfo pointerA = mPointerInfo.getFirst(), pointerB = mPointerInfo.getLast(); - PointF a = pointerA.getPrevious(), b = pointerB.getPrevious(); - if (a == null || b == null) { - a = pointerA.getCurrent(); - b = pointerB.getCurrent(); - } - - return PointUtils.distance(a, b); - } - - /** Returns the time of the last event related to the gesture. */ - public long getEventTime() { - return mLastEventTime; - } - - /** Returns true if the scale gesture is in progress and false otherwise. */ - public boolean isInProgress() { - return getPointersDown() == 2; - } - - /* Sends the requested scale gesture notification to the listener. */ - private void sendScaleGesture(EventType eventType) { - switch (eventType) { - case BEGIN: mListener.onScaleBegin(this); break; - case CONTINUE: mListener.onScale(this); break; - case END: mListener.onScaleEnd(this); break; - } - } - - /* - * Returns the pointer info corresponding to the given pointer index, or null if the pointer - * isn't one that's being tracked. - */ - private PointerInfo pointerInfoForEventIndex(MotionEvent event, int index) { - int id = event.getPointerId(index); - for (PointerInfo pointerInfo : mPointerInfo) { - if (pointerInfo.getId() == id) { - return pointerInfo; - } - } - return null; - } - - private enum EventType { - BEGIN, - CONTINUE, - END, - } - - /* Encapsulates information about one of the two fingers involved in the gesture. */ - private static class PointerInfo { - /* A free list that recycles pointer info objects, to reduce GC pauses. */ - private static Stack sPointerInfoFreeList; - - private int mId; - private PointF mCurrent, mPrevious; - - private PointerInfo() { - // External users should use create() instead. - } - - /* Creates or recycles a new PointerInfo instance from an event and a pointer index. */ - public static PointerInfo create(MotionEvent event, int index) { - if (sPointerInfoFreeList == null) { - sPointerInfoFreeList = new Stack(); - } - - PointerInfo pointerInfo; - if (sPointerInfoFreeList.empty()) { - pointerInfo = new PointerInfo(); - } else { - pointerInfo = sPointerInfoFreeList.pop(); - } - - pointerInfo.populate(event, index); - return pointerInfo; - } - - /* - * Fills in the fields of this instance from the given motion event and pointer index - * within that event. - */ - public void populate(MotionEvent event, int index) { - mId = event.getPointerId(index); - mPrevious = mCurrent; - mCurrent = new PointF(event.getX(index), event.getY(index)); - } - - public void recycle() { - mId = -1; - mPrevious = mCurrent = null; - sPointerInfoFreeList.push(this); - } - - public int getId() { return mId; } - public PointF getCurrent() { return mCurrent; } - public PointF getPrevious() { return mPrevious; } - - @Override - public String toString() { - if (mId == -1) { - return "(up)"; - } - - try { - String prevString; - if (mPrevious == null) { - prevString = "n/a"; - } else { - prevString = PointUtils.toJSON(mPrevious).toString(); - } - - // The current position should always be non-null. - String currentString = PointUtils.toJSON(mCurrent).toString(); - return "id=" + mId + " cur=" + currentString + " prev=" + prevString; - } catch (JSONException e) { - throw new RuntimeException(e); - } - } - } - - public static interface SimpleScaleGestureListener { - public boolean onScale(SimpleScaleGestureDetector detector); - public boolean onScaleBegin(SimpleScaleGestureDetector detector); - public void onScaleEnd(SimpleScaleGestureDetector detector); - } -} - diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java deleted file mode 100644 index f24a5b7adaa1..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/ui/SubdocumentScrollHelper.java +++ /dev/null @@ -1,140 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Android code. - * - * The Initial Developer of the Original Code is Mozilla Foundation. - * Portions created by the Initial Developer are Copyright (C) 2012 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Kartikaya Gupta - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -package org.mozilla.gecko.ui; - - -import android.graphics.PointF; -import android.os.Handler; -import android.util.Log; - -import org.json.JSONException; -import org.json.JSONObject; -import org.mozilla.gecko.GeckoEventListener; - -class SubdocumentScrollHelper implements GeckoEventListener { - private static final String LOGTAG = "GeckoSubdocumentScrollHelper"; - - private static String MESSAGE_PANNING_OVERRIDE = "Panning:Override"; - private static String MESSAGE_CANCEL_OVERRIDE = "Panning:CancelOverride"; - private static String MESSAGE_SCROLL = "Gesture:Scroll"; - private static String MESSAGE_SCROLL_ACK = "Gesture:ScrollAck"; - - private final PanZoomController mPanZoomController; - private final Handler mUiHandler; - - private boolean mOverridePanning; - private boolean mOverrideScrollAck; - private boolean mOverrideScrollPending; - private boolean mScrollSucceeded; - - SubdocumentScrollHelper(PanZoomController controller) { - mPanZoomController = controller; - // mUiHandler will be bound to the UI thread since that's where this constructor runs - mUiHandler = new Handler(); - - //GeckoAppShell.registerGeckoEventListener(MESSAGE_PANNING_OVERRIDE, this); - //GeckoAppShell.registerGeckoEventListener(MESSAGE_CANCEL_OVERRIDE, this); - //GeckoAppShell.registerGeckoEventListener(MESSAGE_SCROLL_ACK, this); - } - - boolean scrollBy(PointF displacement) { - if (!mOverridePanning) { - return false; - } - - if (!mOverrideScrollAck) { - mOverrideScrollPending = true; - return true; - } - - mOverrideScrollAck = false; - mOverrideScrollPending = false; - - JSONObject json = new JSONObject(); - try { - json.put("x", displacement.x); - json.put("y", displacement.y); - } catch (JSONException e) { - Log.e(LOGTAG, "Error forming subwindow scroll message: ", e); - } - //GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent(MESSAGE_SCROLL, json.toString())); - - return true; - } - - void cancel() { - mOverridePanning = false; - } - - boolean scrolling() { - return mOverridePanning; - } - - boolean lastScrollSucceeded() { - return mScrollSucceeded; - } - - // GeckoEventListener implementation - - public void handleMessage(final String event, final JSONObject message) { - // this comes in on the gecko thread; hand off the handling to the UI thread - mUiHandler.post(new Runnable() { - public void run() { - Log.i(LOGTAG, "Got message: " + event); - try { - if (MESSAGE_PANNING_OVERRIDE.equals(event)) { - mOverridePanning = true; - mOverrideScrollAck = true; - mOverrideScrollPending = false; - mScrollSucceeded = true; - } else if (MESSAGE_CANCEL_OVERRIDE.equals(event)) { - mOverridePanning = false; - } else if (MESSAGE_SCROLL_ACK.equals(event)) { - mOverrideScrollAck = true; - mScrollSucceeded = message.getBoolean("scrolled"); - if (mOverridePanning && mOverrideScrollPending) { - scrollBy(mPanZoomController.getDisplacement()); - } - } - } catch (Exception e) { - Log.e(LOGTAG, "Exception handling message", e); - } - } - }); - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java b/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java deleted file mode 100644 index b4bb249c4d5f..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/java/org/mozilla/gecko/util/FloatUtils.java +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package org.mozilla.gecko.util; - -import android.graphics.PointF; - -import java.lang.IllegalArgumentException; - -public final class FloatUtils { - private FloatUtils() {} - - public static boolean fuzzyEquals(float a, float b) { - return (Math.abs(a - b) < 1e-6); - } - - public static boolean fuzzyEquals(PointF a, PointF b) { - return fuzzyEquals(a.x, b.x) && fuzzyEquals(a.y, b.y); - } - - /* - * Returns the value that represents a linear transition between `from` and `to` at time `t`, - * which is on the scale [0, 1). Thus with t = 0.0f, this returns `from`; with t = 1.0f, this - * returns `to`; with t = 0.5f, this returns the value halfway from `from` to `to`. - */ - public static float interpolate(float from, float to, float t) { - return from + (to - from) * t; - } - - /** - * Returns 'value', clamped so that it isn't any lower than 'low', and it - * isn't any higher than 'high'. - */ - public static float clamp(float value, float low, float high) { - if (high < low) { - throw new IllegalArgumentException( - "clamp called with invalid parameters (" + high + " < " + low + ")" ); - } - return Math.max(low, Math.min(high, value)); - } -} diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png deleted file mode 100644 index 729dbcd82ebf..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/base.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png deleted file mode 100644 index a3f5fd4d80c0..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/calc.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png deleted file mode 100644 index 72713b58a39a..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d1.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png deleted file mode 100644 index 4a1070335804..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d2.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png deleted file mode 100644 index 2150c890ed6f..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d3.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png deleted file mode 100644 index 8a12a76b46ca..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d4.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png deleted file mode 100644 index 5a72e1701b3c..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d5.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png deleted file mode 100644 index 3abb776699ab..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d6.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png deleted file mode 100644 index 9e46db76a416..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d7.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png deleted file mode 100644 index c6091ae0ff7e..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d8.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png deleted file mode 100644 index 978606d5b462..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/d9.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png deleted file mode 100644 index b3ee11426a04..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/draw.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png deleted file mode 100644 index c58d276e7085..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/dummy_page.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png deleted file mode 100644 index 96a442e5b8e9..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png deleted file mode 100644 index d5f16694f342..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png deleted file mode 100644 index 5909f05bf089..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/impress.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png deleted file mode 100644 index 2ef86417e69e..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/lo_icon.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png deleted file mode 100644 index 7e8e2a05e2da..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/main.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png deleted file mode 100644 index 50b8dc863bff..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/math.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png deleted file mode 100644 index 7e8e2a05e2da..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-hdpi/startcenter.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png deleted file mode 100644 index 611592b5167a..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/background.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png deleted file mode 100644 index 729dbcd82ebf..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/base.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png deleted file mode 100644 index a3f5fd4d80c0..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/calc.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png deleted file mode 100644 index ab34ae5638e1..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/docu.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png deleted file mode 100644 index b3ee11426a04..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/draw.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png deleted file mode 100644 index 359047dfa4ed..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png deleted file mode 100644 index 835fc9290727..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png deleted file mode 100644 index 5909f05bf089..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/impress.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png deleted file mode 100644 index 4f3f89beadc2..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/lo_icon.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png deleted file mode 100644 index 3ce69155c6b5..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/shadow.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png deleted file mode 100644 index 2f4abcb280cd..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-mdpi/writer.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png deleted file mode 100644 index 729dbcd82ebf..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/base.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png deleted file mode 100644 index a3f5fd4d80c0..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/calc.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png deleted file mode 100644 index b3ee11426a04..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/draw.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png deleted file mode 100644 index 71c6d760f051..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png deleted file mode 100644 index c8005425416a..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/ic_status_logo.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png deleted file mode 100644 index 5909f05bf089..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/impress.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png deleted file mode 100644 index 2f4abcb280cd..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xhdpi/writer.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png deleted file mode 100644 index 4df18946442e..000000000000 Binary files a/android/experimental/LOAndroid2/app/src/main/res/drawable-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml b/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index 7b53d58a2b5c..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml b/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml deleted file mode 100644 index e9709c90d729..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/menu/main.xml +++ /dev/null @@ -1,8 +0,0 @@ -

- - diff --git a/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml b/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc81644461..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml b/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml deleted file mode 100644 index f8e207d4e00e..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/values/colors.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - #FFECF0F3 - #FFCED7DE - #FF292C29 - #FF363B40 - #33000000 - #1A000000 - #33FFFFFF - #1AFFFFFF - - - #FF696D71 - - - #FF565B60 - - - #FFA5ACB2 - - - #FFB9C1C7 - - - #FF545654 - - - #FF3F423F - - - - #222222 - #777777 - #9198A1 - - - #FFFFFF - #DDDDDD - #A4A7A9 - - - #999999 - - - #666666 - #7F828A - - - #FF9500 - #D06BFF - - - #22629E - - #000000 - #ffffff - #000000 - #ffffff - - #FF222222 - #FF2AA1FE - #FFD1D5DA - #FFB3C2CE - #FFDDE4EA - - #ffffff - #FFFF9500 - #FFD06BFF - #dddddd - #bbbbbb - #4D000000 - #ffffff - - #FFF - #DDD - #000 - #666 - - #A6A6A6 - #000 - #FFF - #b14646 - #12000000 - - #FFF5F7F9 - - #D1D9E1 - - diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml b/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml deleted file mode 100644 index 47c82246738c..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml b/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml deleted file mode 100644 index 8864167560f8..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - LOAndroid - Hello world! - Settings - - diff --git a/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml b/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml deleted file mode 100644 index ff6c9d2c0fb9..000000000000 --- a/android/experimental/LOAndroid2/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - diff --git a/android/experimental/LOAndroid2/build.gradle b/android/experimental/LOAndroid2/build.gradle deleted file mode 100644 index e33f142839c8..000000000000 --- a/android/experimental/LOAndroid2/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. - -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.12.+' - } -} - -allprojects { - repositories { - mavenCentral() - } -} diff --git a/android/experimental/LOAndroid2/gradle.properties b/android/experimental/LOAndroid2/gradle.properties deleted file mode 100644 index 5d08ba75bb97..000000000000 --- a/android/experimental/LOAndroid2/gradle.properties +++ /dev/null @@ -1,18 +0,0 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Settings specified in this file will override any Gradle settings -# configured through the IDE. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file diff --git a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar b/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 8c0fb64a8698..000000000000 Binary files a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties b/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 2405fae37f2f..000000000000 --- a/android/experimental/LOAndroid2/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Mon Jun 09 10:23:20 CEST 2014 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip diff --git a/android/experimental/LOAndroid2/gradlew b/android/experimental/LOAndroid2/gradlew deleted file mode 100755 index 91a7e269e19d..000000000000 --- a/android/experimental/LOAndroid2/gradlew +++ /dev/null @@ -1,164 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/experimental/LOAndroid2/gradlew.bat b/android/experimental/LOAndroid2/gradlew.bat deleted file mode 100644 index aec99730b4e8..000000000000 --- a/android/experimental/LOAndroid2/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/android/experimental/LOAndroid2/settings.gradle b/android/experimental/LOAndroid2/settings.gradle deleted file mode 100644 index e7b4def49cb5..000000000000 --- a/android/experimental/LOAndroid2/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' -- cgit