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"
12 #include "SurfaceViewWrapperSupport.h"
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() {
28 ANativeWindow_release(mNativeWindow
);
32 already_AddRefed
<gfx::DrawTarget
>
33 AndroidCompositorWidget::StartRemoteDrawingInRegion(
34 const LayoutDeviceIntRegion
& aInvalidRegion
,
35 layers::BufferMode
* aBufferMode
) {
37 EGLNativeWindowType window
= GetEGLNativeWindow();
38 JNIEnv
* const env
= jni::GetEnvForThread();
40 ANativeWindow_fromSurface(env
, reinterpret_cast<jobject
>(window
));
42 mFormat
= ANativeWindow_getFormat(mNativeWindow
);
43 ANativeWindow_acquire(mNativeWindow
);
49 if (mFormat
!= WINDOW_FORMAT_RGBA_8888
&&
50 mFormat
!= WINDOW_FORMAT_RGBX_8888
) {
51 gfxCriticalNoteOnce
<< "Non supported format: " << mFormat
;
55 // XXX Handle inOutDirtyBounds
56 if (ANativeWindow_lock(mNativeWindow
, &mBuffer
, nullptr) != 0) {
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
,
74 void AndroidCompositorWidget::EndRemoteDrawingInRegion(
75 gfx::DrawTarget
* aDrawTarget
, const LayoutDeviceIntRegion
& aInvalidRegion
) {
76 ANativeWindow_unlockAndPost(mNativeWindow
);
79 bool AndroidCompositorWidget::OnResumeComposition() {
80 OnCompositorSurfaceChanged();
83 gfxCriticalError() << "OnResumeComposition called with null Surface";
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
90 if (SurfaceViewWrapperSupport::IsSurfaceAbandoned(mSurface
)) {
91 MOZ_CRASH("Compositor resumed with abandoned Surface");
97 EGLNativeWindowType
AndroidCompositorWidget::GetEGLNativeWindow() {
98 return (EGLNativeWindowType
)mSurface
.Get();
101 LayoutDeviceIntSize
AndroidCompositorWidget::GetClientSize() {
105 void AndroidCompositorWidget::NotifyClientSizeChanged(
106 const LayoutDeviceIntSize
& aClientSize
) {
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