summaryrefslogtreecommitdiffstats
path: root/widget/android/AndroidCompositorWidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'widget/android/AndroidCompositorWidget.cpp')
-rw-r--r--widget/android/AndroidCompositorWidget.cpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/widget/android/AndroidCompositorWidget.cpp b/widget/android/AndroidCompositorWidget.cpp
new file mode 100644
index 0000000000..a7eeb665e1
--- /dev/null
+++ b/widget/android/AndroidCompositorWidget.cpp
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=2 et tw=80 : */
+/* 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/. */
+
+#include "AndroidCompositorWidget.h"
+
+#include "mozilla/gfx/Logging.h"
+#include "mozilla/widget/PlatformWidgetTypes.h"
+#include "nsWindow.h"
+
+namespace mozilla {
+namespace widget {
+
+AndroidCompositorWidget::AndroidCompositorWidget(
+ const AndroidCompositorWidgetInitData& aInitData,
+ const layers::CompositorOptions& aOptions)
+ : CompositorWidget(aOptions),
+ mWidgetId(aInitData.widgetId()),
+ mNativeWindow(nullptr),
+ mFormat(WINDOW_FORMAT_RGBA_8888),
+ mClientSize(aInitData.clientSize()) {}
+
+AndroidCompositorWidget::~AndroidCompositorWidget() {
+ if (mNativeWindow) {
+ ANativeWindow_release(mNativeWindow);
+ }
+}
+
+already_AddRefed<gfx::DrawTarget>
+AndroidCompositorWidget::StartRemoteDrawingInRegion(
+ const LayoutDeviceIntRegion& aInvalidRegion,
+ layers::BufferMode* aBufferMode) {
+ if (!mNativeWindow) {
+ EGLNativeWindowType window = GetEGLNativeWindow();
+ JNIEnv* const env = jni::GetEnvForThread();
+ mNativeWindow =
+ ANativeWindow_fromSurface(env, reinterpret_cast<jobject>(window));
+ if (mNativeWindow) {
+ mFormat = ANativeWindow_getFormat(mNativeWindow);
+ ANativeWindow_acquire(mNativeWindow);
+ } else {
+ return nullptr;
+ }
+ }
+
+ if (mFormat != WINDOW_FORMAT_RGBA_8888 &&
+ mFormat != WINDOW_FORMAT_RGBX_8888) {
+ gfxCriticalNoteOnce << "Non supported format: " << mFormat;
+ return nullptr;
+ }
+
+ // XXX Handle inOutDirtyBounds
+ if (ANativeWindow_lock(mNativeWindow, &mBuffer, nullptr) != 0) {
+ return nullptr;
+ }
+
+ const int bpp = 4;
+ gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
+ if (mFormat == WINDOW_FORMAT_RGBX_8888) {
+ format = gfx::SurfaceFormat::R8G8B8X8;
+ }
+
+ RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateDrawTargetForData(
+ gfx::BackendType::SKIA, static_cast<unsigned char*>(mBuffer.bits),
+ gfx::IntSize(mBuffer.width, mBuffer.height), mBuffer.stride * bpp, format,
+ true);
+
+ return dt.forget();
+}
+
+void AndroidCompositorWidget::EndRemoteDrawingInRegion(
+ gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
+ ANativeWindow_unlockAndPost(mNativeWindow);
+}
+
+bool AndroidCompositorWidget::OnResumeComposition() {
+ OnCompositorSurfaceChanged();
+
+ if (!mSurface) {
+ gfxCriticalError() << "OnResumeComposition called with null Surface";
+ return false;
+ }
+
+ return true;
+}
+
+EGLNativeWindowType AndroidCompositorWidget::GetEGLNativeWindow() {
+ return (EGLNativeWindowType)mSurface.Get();
+}
+
+LayoutDeviceIntSize AndroidCompositorWidget::GetClientSize() {
+ return mClientSize;
+}
+
+void AndroidCompositorWidget::NotifyClientSizeChanged(
+ const LayoutDeviceIntSize& aClientSize) {
+ mClientSize =
+ LayoutDeviceIntSize(std::min(aClientSize.width, MOZ_WIDGET_MAX_SIZE),
+ std::min(aClientSize.height, MOZ_WIDGET_MAX_SIZE));
+}
+
+} // namespace widget
+} // namespace mozilla