зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1238876 - Move StartRemoteDrawing() implementation from nsWindow to nsScreenGonk r=mwu
This commit is contained in:
Родитель
1bdd937ff4
Коммит
41edebedd1
|
@ -16,6 +16,7 @@
|
|||
#include "android/log.h"
|
||||
#include "GLContext.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "mozilla/Hal.h"
|
||||
|
@ -129,6 +130,8 @@ nsScreenGonk::nsScreenGonk(uint32_t aId,
|
|||
, mEGLDisplay(EGL_NO_DISPLAY)
|
||||
, mEGLSurface(EGL_NO_SURFACE)
|
||||
, mGLContext(nullptr)
|
||||
, mFramebuffer(nullptr)
|
||||
, mMappedBuffer(nullptr)
|
||||
{
|
||||
if (mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_WIDTH, &mVirtualBounds.width) ||
|
||||
mNativeWindow->query(mNativeWindow.get(), NATIVE_WINDOW_HEIGHT, &mVirtualBounds.height) ||
|
||||
|
@ -368,6 +371,126 @@ nsScreenGonk::BringToTop(nsWindow* aWindow)
|
|||
mTopWindows.InsertElementAt(0, aWindow);
|
||||
}
|
||||
|
||||
static gralloc_module_t const*
|
||||
gralloc_module()
|
||||
{
|
||||
hw_module_t const *module;
|
||||
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<gralloc_module_t const*>(module);
|
||||
}
|
||||
|
||||
static SurfaceFormat
|
||||
HalFormatToSurfaceFormat(int aHalFormat)
|
||||
{
|
||||
switch (aHalFormat) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
// Needs RB swap
|
||||
return SurfaceFormat::B8G8R8A8;
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
// Needs RB swap
|
||||
return SurfaceFormat::B8G8R8X8;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
return SurfaceFormat::B8G8R8A8;
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
return SurfaceFormat::R5G6B5_UINT16;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled HAL pixel format");
|
||||
return SurfaceFormat::UNKNOWN; // not reached
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
NeedsRBSwap(int aHalFormat)
|
||||
{
|
||||
switch (aHalFormat) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
return true;
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
return true;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
return false;
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
return false;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled HAL pixel format");
|
||||
return false; // not reached
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsScreenGonk::StartRemoteDrawing()
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
MOZ_ASSERT(!mFramebuffer);
|
||||
MOZ_ASSERT(!mMappedBuffer);
|
||||
|
||||
mFramebuffer = DequeueBuffer();
|
||||
int width = mFramebuffer->width, height = mFramebuffer->height;
|
||||
if (gralloc_module()->lock(gralloc_module(), mFramebuffer->handle,
|
||||
GRALLOC_USAGE_SW_READ_NEVER |
|
||||
GRALLOC_USAGE_SW_WRITE_OFTEN |
|
||||
GRALLOC_USAGE_HW_FB,
|
||||
0, 0, width, height,
|
||||
reinterpret_cast<void**>(&mMappedBuffer))) {
|
||||
EndRemoteDrawing();
|
||||
return nullptr;
|
||||
}
|
||||
SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
|
||||
mFramebufferTarget = Factory::CreateDrawTargetForData(
|
||||
BackendType::CAIRO,
|
||||
mMappedBuffer,
|
||||
IntSize(width, height),
|
||||
mFramebuffer->stride * gfx::BytesPerPixel(format),
|
||||
format);
|
||||
if (!mFramebufferTarget) {
|
||||
MOZ_CRASH("nsWindow::StartRemoteDrawing failed in CreateDrawTargetForData");
|
||||
}
|
||||
if (!mBackBuffer ||
|
||||
mBackBuffer->GetSize() != mFramebufferTarget->GetSize() ||
|
||||
mBackBuffer->GetFormat() != mFramebufferTarget->GetFormat()) {
|
||||
mBackBuffer = mFramebufferTarget->CreateSimilarDrawTarget(
|
||||
mFramebufferTarget->GetSize(), mFramebufferTarget->GetFormat());
|
||||
}
|
||||
RefPtr<DrawTarget> buffer(mBackBuffer);
|
||||
return buffer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsScreenGonk::EndRemoteDrawing()
|
||||
{
|
||||
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
|
||||
|
||||
if (mFramebufferTarget && mFramebuffer) {
|
||||
IntSize size = mFramebufferTarget->GetSize();
|
||||
Rect rect(0, 0, size.width, size.height);
|
||||
RefPtr<SourceSurface> source = mBackBuffer->Snapshot();
|
||||
mFramebufferTarget->DrawSurface(source, rect, rect);
|
||||
|
||||
// Convert from BGR to RGB
|
||||
// XXX this is a temporary solution. It consumes extra cpu cycles,
|
||||
// it should not be used on product device.
|
||||
if (NeedsRBSwap(GetSurfaceFormat())) {
|
||||
LOGE("Very slow composition path, it should not be used on product!!!");
|
||||
SurfaceFormat format = HalFormatToSurfaceFormat(GetSurfaceFormat());
|
||||
gfxUtils::ConvertBGRAtoRGBA(
|
||||
mMappedBuffer,
|
||||
mFramebuffer->stride * mFramebuffer->height * gfx::BytesPerPixel(format));
|
||||
}
|
||||
}
|
||||
if (mMappedBuffer) {
|
||||
MOZ_ASSERT(mFramebuffer);
|
||||
gralloc_module()->unlock(gralloc_module(), mFramebuffer->handle);
|
||||
mMappedBuffer = nullptr;
|
||||
}
|
||||
if (mFramebuffer) {
|
||||
QueueBuffer(mFramebuffer);
|
||||
}
|
||||
mFramebuffer = nullptr;
|
||||
mFramebufferTarget = nullptr;
|
||||
}
|
||||
|
||||
ANativeWindowBuffer*
|
||||
nsScreenGonk::DequeueBuffer()
|
||||
{
|
||||
|
|
|
@ -82,8 +82,8 @@ public:
|
|||
ScreenConfiguration GetConfiguration();
|
||||
bool IsPrimaryScreen();
|
||||
|
||||
ANativeWindowBuffer* DequeueBuffer();
|
||||
bool QueueBuffer(ANativeWindowBuffer* buf);
|
||||
already_AddRefed<mozilla::gfx::DrawTarget> StartRemoteDrawing();
|
||||
void EndRemoteDrawing();
|
||||
|
||||
#if ANDROID_VERSION >= 17
|
||||
android::DisplaySurface* GetDisplaySurface();
|
||||
|
@ -122,6 +122,9 @@ public:
|
|||
nsWindow* GetMirroringWidget(); // Primary screen only
|
||||
|
||||
protected:
|
||||
ANativeWindowBuffer* DequeueBuffer();
|
||||
bool QueueBuffer(ANativeWindowBuffer* buf);
|
||||
|
||||
uint32_t mId;
|
||||
NotifyDisplayChangedEvent mEventVisibility;
|
||||
int32_t mColorDepth;
|
||||
|
@ -145,6 +148,26 @@ protected:
|
|||
hwc_surface_t mEGLSurface;
|
||||
RefPtr<mozilla::gl::GLContext> mGLContext;
|
||||
RefPtr<nsWindow> mMirroringWidget; // Primary screen only
|
||||
|
||||
// If we're using a BasicCompositor, these fields are temporarily
|
||||
// set during frame composition. They wrap the hardware
|
||||
// framebuffer.
|
||||
RefPtr<mozilla::gfx::DrawTarget> mFramebufferTarget;
|
||||
ANativeWindowBuffer* mFramebuffer;
|
||||
/**
|
||||
* Points to a mapped gralloc buffer between calls to lock and unlock.
|
||||
* Should be null outside of the lock-unlock pair.
|
||||
*/
|
||||
uint8_t* mMappedBuffer;
|
||||
// If we're using a BasicCompositor, this is our window back
|
||||
// buffer. The gralloc framebuffer driver expects us to draw the
|
||||
// entire framebuffer on every frame, but gecko expects the
|
||||
// windowing system to be tracking buffer updates for invalidated
|
||||
// regions. We get stuck holding that bag.
|
||||
//
|
||||
// Only accessed on the compositor thread, except during
|
||||
// destruction.
|
||||
RefPtr<mozilla::gfx::DrawTarget> mBackBuffer;
|
||||
};
|
||||
|
||||
class nsScreenManagerGonk final : public nsIScreenManager
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxUtils.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLContextEGL.h"
|
||||
|
@ -66,8 +65,6 @@ static nsWindow *gFocusedWindow = nullptr;
|
|||
NS_IMPL_ISUPPORTS_INHERITED0(nsWindow, nsBaseWidget)
|
||||
|
||||
nsWindow::nsWindow()
|
||||
: mFramebuffer(nullptr)
|
||||
, mMappedBuffer(nullptr)
|
||||
{
|
||||
RefPtr<nsScreenManagerGonk> screenManager = nsScreenManagerGonk::GetInstance();
|
||||
screenManager->Initialize();
|
||||
|
@ -623,116 +620,17 @@ nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen*)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static gralloc_module_t const*
|
||||
gralloc_module()
|
||||
{
|
||||
hw_module_t const *module;
|
||||
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
|
||||
return nullptr;
|
||||
}
|
||||
return reinterpret_cast<gralloc_module_t const*>(module);
|
||||
}
|
||||
|
||||
static SurfaceFormat
|
||||
HalFormatToSurfaceFormat(int aHalFormat)
|
||||
{
|
||||
switch (aHalFormat) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
// Needs RB swap
|
||||
return SurfaceFormat::B8G8R8A8;
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
// Needs RB swap
|
||||
return SurfaceFormat::B8G8R8X8;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
return SurfaceFormat::B8G8R8A8;
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
return SurfaceFormat::R5G6B5_UINT16;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled HAL pixel format");
|
||||
return SurfaceFormat::UNKNOWN; // not reached
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
NeedsRBSwap(int aHalFormat)
|
||||
{
|
||||
switch (aHalFormat) {
|
||||
case HAL_PIXEL_FORMAT_RGBA_8888:
|
||||
return true;
|
||||
case HAL_PIXEL_FORMAT_RGBX_8888:
|
||||
return true;
|
||||
case HAL_PIXEL_FORMAT_BGRA_8888:
|
||||
return false;
|
||||
case HAL_PIXEL_FORMAT_RGB_565:
|
||||
return false;
|
||||
default:
|
||||
MOZ_CRASH("Unhandled HAL pixel format");
|
||||
return false; // not reached
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
nsWindow::StartRemoteDrawing()
|
||||
{
|
||||
mFramebuffer = mScreen->DequeueBuffer();
|
||||
int width = mFramebuffer->width, height = mFramebuffer->height;
|
||||
if (gralloc_module()->lock(gralloc_module(), mFramebuffer->handle,
|
||||
GRALLOC_USAGE_SW_READ_NEVER |
|
||||
GRALLOC_USAGE_SW_WRITE_OFTEN |
|
||||
GRALLOC_USAGE_HW_FB,
|
||||
0, 0, width, height,
|
||||
reinterpret_cast<void**>(&mMappedBuffer))) {
|
||||
EndRemoteDrawing();
|
||||
return nullptr;
|
||||
}
|
||||
SurfaceFormat format = HalFormatToSurfaceFormat(mScreen->GetSurfaceFormat());
|
||||
mFramebufferTarget = Factory::CreateDrawTargetForData(
|
||||
BackendType::CAIRO,
|
||||
mMappedBuffer,
|
||||
IntSize(width, height),
|
||||
mFramebuffer->stride * gfx::BytesPerPixel(format),
|
||||
format);
|
||||
if (!mFramebufferTarget) {
|
||||
MOZ_CRASH("nsWindow::StartRemoteDrawing failed in CreateDrawTargetForData");
|
||||
}
|
||||
if (!mBackBuffer ||
|
||||
mBackBuffer->GetSize() != mFramebufferTarget->GetSize() ||
|
||||
mBackBuffer->GetFormat() != mFramebufferTarget->GetFormat()) {
|
||||
mBackBuffer = mFramebufferTarget->CreateSimilarDrawTarget(
|
||||
mFramebufferTarget->GetSize(), mFramebufferTarget->GetFormat());
|
||||
}
|
||||
RefPtr<DrawTarget> buffer(mBackBuffer);
|
||||
RefPtr<DrawTarget> buffer = mScreen->StartRemoteDrawing();
|
||||
return buffer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::EndRemoteDrawing()
|
||||
{
|
||||
if (mFramebufferTarget && mFramebuffer) {
|
||||
IntSize size = mFramebufferTarget->GetSize();
|
||||
Rect rect(0, 0, size.width, size.height);
|
||||
RefPtr<SourceSurface> source = mBackBuffer->Snapshot();
|
||||
mFramebufferTarget->DrawSurface(source, rect, rect);
|
||||
|
||||
// Convert from BGR to RGB
|
||||
// XXX this is a temporary solution. It consumes extra cpu cycles,
|
||||
// it should not be used on product device.
|
||||
if (NeedsRBSwap(mScreen->GetSurfaceFormat())) {
|
||||
LOGE("Very slow composition path, it should not be used on product!!!");
|
||||
SurfaceFormat format = HalFormatToSurfaceFormat(mScreen->GetSurfaceFormat());
|
||||
gfxUtils::ConvertBGRAtoRGBA(
|
||||
mMappedBuffer,
|
||||
mFramebuffer->stride * mFramebuffer->height * gfx::BytesPerPixel(format));
|
||||
mMappedBuffer = nullptr;
|
||||
gralloc_module()->unlock(gralloc_module(), mFramebuffer->handle);
|
||||
}
|
||||
}
|
||||
if (mFramebuffer) {
|
||||
mScreen->QueueBuffer(mFramebuffer);
|
||||
}
|
||||
mFramebuffer = nullptr;
|
||||
mFramebufferTarget = nullptr;
|
||||
mScreen->EndRemoteDrawing();
|
||||
}
|
||||
|
||||
float
|
||||
|
|
|
@ -138,25 +138,6 @@ protected:
|
|||
bool mVisible;
|
||||
InputContext mInputContext;
|
||||
nsCOMPtr<nsIIdleServiceInternal> mIdleService;
|
||||
// If we're using a BasicCompositor, these fields are temporarily
|
||||
// set during frame composition. They wrap the hardware
|
||||
// framebuffer.
|
||||
RefPtr<mozilla::gfx::DrawTarget> mFramebufferTarget;
|
||||
ANativeWindowBuffer* mFramebuffer;
|
||||
/**
|
||||
* Points to a mapped gralloc buffer between calls to lock and unlock.
|
||||
* Should be null outside of the lock-unlock pair.
|
||||
*/
|
||||
uint8_t* mMappedBuffer;
|
||||
// If we're using a BasicCompositor, this is our window back
|
||||
// buffer. The gralloc framebuffer driver expects us to draw the
|
||||
// entire framebuffer on every frame, but gecko expects the
|
||||
// windowing system to be tracking buffer updates for invalidated
|
||||
// regions. We get stuck holding that bag.
|
||||
//
|
||||
// Only accessed on the compositor thread, except during
|
||||
// destruction.
|
||||
RefPtr<mozilla::gfx::DrawTarget> mBackBuffer;
|
||||
|
||||
virtual ~nsWindow();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче