forked from mirrors/gecko-dev
Since bug 1747116 landed, if the compositor is reinitialized whilst the Android Surface is invalid, we avoid crashing when querying the window size and instead keep the compositor in a paused state. However, in this case we will believe the widget size is 0x0 until the compositor is eventually resumed. If webrender receives a display list during this time, it will set an empty view rect. This means when the compositor is subsequently resumed webrender believes it has nothing to render, and we get stuck in a state where nothing is ever rendered to the screen. This patch initializes the AndroidCompositorWidget with an initial size, which avoids the problem. Differential Revision: https://phabricator.services.mozilla.com/D135711
112 lines
3.4 KiB
C++
112 lines
3.4 KiB
C++
/* -*- 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;
|
|
}
|
|
|
|
JNIEnv* const env = jni::GetEnvForThread();
|
|
ANativeWindow* const nativeWindow =
|
|
ANativeWindow_fromSurface(env, reinterpret_cast<jobject>(mSurface.Get()));
|
|
if (!nativeWindow) {
|
|
gfxCriticalError() << "OnResumeComposition called with invalid Surface";
|
|
return false;
|
|
}
|
|
|
|
const int32_t width = ANativeWindow_getWidth(nativeWindow);
|
|
const int32_t height = ANativeWindow_getHeight(nativeWindow);
|
|
mClientSize = LayoutDeviceIntSize(width, height);
|
|
|
|
ANativeWindow_release(nativeWindow);
|
|
|
|
return true;
|
|
}
|
|
|
|
EGLNativeWindowType AndroidCompositorWidget::GetEGLNativeWindow() {
|
|
return (EGLNativeWindowType)mSurface.Get();
|
|
}
|
|
|
|
LayoutDeviceIntSize AndroidCompositorWidget::GetClientSize() {
|
|
return mClientSize;
|
|
}
|
|
|
|
} // namespace widget
|
|
} // namespace mozilla
|