Bug 1794292 - [ANGLE] cherry-pick init-gl-point-size. r=gfx-reviewers,bradwerth
[gecko.git] / widget / android / AndroidCompositorWidget.cpp
blobedbdad6bb6139ea5379ee0c09b65bc1b0637fabc
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=2 et tw=80 : */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "AndroidCompositorWidget.h"
9 #include "mozilla/gfx/Logging.h"
10 #include "mozilla/widget/PlatformWidgetTypes.h"
11 #include "nsWindow.h"
12 #include "SurfaceViewWrapperSupport.h"
14 namespace mozilla {
15 namespace widget {
17 AndroidCompositorWidget::AndroidCompositorWidget(
18 const AndroidCompositorWidgetInitData& aInitData,
19 const layers::CompositorOptions& aOptions)
20 : CompositorWidget(aOptions),
21 mWidgetId(aInitData.widgetId()),
22 mNativeWindow(nullptr),
23 mFormat(WINDOW_FORMAT_RGBA_8888),
24 mClientSize(aInitData.clientSize()) {}
26 AndroidCompositorWidget::~AndroidCompositorWidget() {
27 if (mNativeWindow) {
28 ANativeWindow_release(mNativeWindow);
32 already_AddRefed<gfx::DrawTarget>
33 AndroidCompositorWidget::StartRemoteDrawingInRegion(
34 const LayoutDeviceIntRegion& aInvalidRegion,
35 layers::BufferMode* aBufferMode) {
36 if (!mNativeWindow) {
37 EGLNativeWindowType window = GetEGLNativeWindow();
38 JNIEnv* const env = jni::GetEnvForThread();
39 mNativeWindow =
40 ANativeWindow_fromSurface(env, reinterpret_cast<jobject>(window));
41 if (mNativeWindow) {
42 mFormat = ANativeWindow_getFormat(mNativeWindow);
43 ANativeWindow_acquire(mNativeWindow);
44 } else {
45 return nullptr;
49 if (mFormat != WINDOW_FORMAT_RGBA_8888 &&
50 mFormat != WINDOW_FORMAT_RGBX_8888) {
51 gfxCriticalNoteOnce << "Non supported format: " << mFormat;
52 return nullptr;
55 // XXX Handle inOutDirtyBounds
56 if (ANativeWindow_lock(mNativeWindow, &mBuffer, nullptr) != 0) {
57 return nullptr;
60 const int bpp = 4;
61 gfx::SurfaceFormat format = gfx::SurfaceFormat::R8G8B8A8;
62 if (mFormat == WINDOW_FORMAT_RGBX_8888) {
63 format = gfx::SurfaceFormat::R8G8B8X8;
66 RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateDrawTargetForData(
67 gfx::BackendType::SKIA, static_cast<unsigned char*>(mBuffer.bits),
68 gfx::IntSize(mBuffer.width, mBuffer.height), mBuffer.stride * bpp, format,
69 true);
71 return dt.forget();
74 void AndroidCompositorWidget::EndRemoteDrawingInRegion(
75 gfx::DrawTarget* aDrawTarget, const LayoutDeviceIntRegion& aInvalidRegion) {
76 ANativeWindow_unlockAndPost(mNativeWindow);
79 bool AndroidCompositorWidget::OnResumeComposition() {
80 OnCompositorSurfaceChanged();
82 if (!mSurface) {
83 gfxCriticalError() << "OnResumeComposition called with null Surface";
84 return false;
87 // If our Surface is in an abandoned state then we will never succesfully
88 // create an EGL Surface, and will eventually crash. Better to explicitly
89 // crash now.
90 if (SurfaceViewWrapperSupport::IsSurfaceAbandoned(mSurface)) {
91 MOZ_CRASH("Compositor resumed with abandoned Surface");
94 return true;
97 EGLNativeWindowType AndroidCompositorWidget::GetEGLNativeWindow() {
98 return (EGLNativeWindowType)mSurface.Get();
101 LayoutDeviceIntSize AndroidCompositorWidget::GetClientSize() {
102 return mClientSize;
105 void AndroidCompositorWidget::NotifyClientSizeChanged(
106 const LayoutDeviceIntSize& aClientSize) {
107 mClientSize =
108 LayoutDeviceIntSize(std::min(aClientSize.width, MOZ_WIDGET_MAX_SIZE),
109 std::min(aClientSize.height, MOZ_WIDGET_MAX_SIZE));
112 } // namespace widget
113 } // namespace mozilla