fune/gfx/layers/opengl/TextureClientOGL.cpp
Markus Stange 7981f6dc01 Bug 1444432 - Add missing gfx:: qualifiers in TextureClientOGL.cpp. r=jrmuizel
MozReview-Commit-ID: BT33ief5qkt

--HG--
extra : rebase_source : 7709a9d125198880bf7765ef5a4d32ac6ca9e305
2018-04-13 00:13:41 -04:00

245 lines
7.7 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 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 "GLContext.h" // for GLContext, etc
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/TextureClientOGL.h"
#include "mozilla/gfx/2D.h" // for Factory
#include "mozilla/gfx/Point.h" // for IntSize
#include "GLLibraryEGL.h"
#ifdef MOZ_WIDGET_ANDROID
#include <jni.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#endif
using namespace mozilla::gl;
namespace mozilla {
namespace layers {
class CompositableForwarder;
////////////////////////////////////////////////////////////////////////
// AndroidSurface
#ifdef MOZ_WIDGET_ANDROID
already_AddRefed<TextureClient>
AndroidSurfaceTextureData::CreateTextureClient(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize,
bool aContinuous,
gl::OriginPos aOriginPos,
LayersIPCChannel* aAllocator,
TextureFlags aFlags)
{
if (aOriginPos == gl::OriginPos::BottomLeft) {
aFlags |= TextureFlags::ORIGIN_BOTTOM_LEFT;
}
return TextureClient::CreateWithData(
new AndroidSurfaceTextureData(aHandle, aSize, aContinuous),
aFlags, aAllocator
);
}
AndroidSurfaceTextureData::AndroidSurfaceTextureData(AndroidSurfaceTextureHandle aHandle,
gfx::IntSize aSize, bool aContinuous)
: mHandle(aHandle)
, mSize(aSize)
, mContinuous(aContinuous)
{
MOZ_ASSERT(mHandle);
}
AndroidSurfaceTextureData::~AndroidSurfaceTextureData()
{}
void
AndroidSurfaceTextureData::FillInfo(TextureData::Info& aInfo) const
{
aInfo.size = mSize;
aInfo.format = gfx::SurfaceFormat::UNKNOWN;
aInfo.hasIntermediateBuffer = false;
aInfo.hasSynchronization = false;
aInfo.supportsMoz2D = false;
aInfo.canExposeMappedData = false;
}
bool
AndroidSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
aOutDescriptor = SurfaceTextureDescriptor(mHandle,
mSize,
gfx::SurfaceFormat::R8G8B8A8,
mContinuous,
false /* do not ignore transform */);
return true;
}
#endif // MOZ_WIDGET_ANDROID
////////////////////////////////////////////////////////////////////////
// AndroidNativeWindow
#ifdef MOZ_WIDGET_ANDROID
AndroidNativeWindowTextureData*
AndroidNativeWindowTextureData::Create(gfx::IntSize aSize,
gfx::SurfaceFormat aFormat)
{
if (aFormat != gfx::SurfaceFormat::R8G8B8A8 &&
aFormat != gfx::SurfaceFormat::R8G8B8X8 &&
aFormat != gfx::SurfaceFormat::B8G8R8A8 &&
aFormat != gfx::SurfaceFormat::B8G8R8X8 &&
aFormat != gfx::SurfaceFormat::R5G6B5_UINT16) {
return nullptr;
}
auto surface = java::GeckoSurface::LocalRef(
java::SurfaceAllocator::AcquireSurface(aSize.width, aSize.height,
true /* single-buffer mode */));
if (surface) {
return new AndroidNativeWindowTextureData(surface, aSize, aFormat);
}
return nullptr;
}
AndroidNativeWindowTextureData::AndroidNativeWindowTextureData(java::GeckoSurface::Param aSurface,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat)
: mSurface(aSurface)
, mIsLocked(false)
, mSize(aSize)
, mFormat(aFormat)
{
mNativeWindow = ANativeWindow_fromSurface(jni::GetEnvForThread(),
mSurface.Get());
MOZ_ASSERT(mNativeWindow, "Failed to create NativeWindow.");
// SurfaceTextures don't technically support BGR, but we can just pretend to be RGB.
int32_t format = WINDOW_FORMAT_RGBA_8888;
switch (aFormat) {
case gfx::SurfaceFormat::R8G8B8A8:
case gfx::SurfaceFormat::B8G8R8A8:
format = WINDOW_FORMAT_RGBA_8888;
break;
case gfx::SurfaceFormat::R8G8B8X8:
case gfx::SurfaceFormat::B8G8R8X8:
format = WINDOW_FORMAT_RGBX_8888;
break;
case gfx::SurfaceFormat::R5G6B5_UINT16:
format = WINDOW_FORMAT_RGB_565;
break;
default:
MOZ_ASSERT(false, "Unsupported AndroidNativeWindowTextureData format.");
}
DebugOnly<int32_t> r = ANativeWindow_setBuffersGeometry(mNativeWindow,
mSize.width,
mSize.height,
format);
MOZ_ASSERT(r == 0, "ANativeWindow_setBuffersGeometry failed.");
// Ideally here we'd call ANativeWindow_setBuffersTransform() with the
// identity transform, but that is only available on api level >= 26.
// Instead use the SurfaceDescriptor's ignoreTransform flag when serializing.
}
void
AndroidNativeWindowTextureData::FillInfo(TextureData::Info& aInfo) const
{
aInfo.size = mSize;
aInfo.format = mFormat;
aInfo.hasIntermediateBuffer = false;
aInfo.hasSynchronization = false;
aInfo.supportsMoz2D = true;
aInfo.canExposeMappedData = false;
aInfo.canConcurrentlyReadLock = false;
}
bool
AndroidNativeWindowTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
{
aOutDescriptor = SurfaceTextureDescriptor(mSurface->GetHandle(),
mSize,
mFormat,
false /* not continuous */,
true /* ignore transform */);
return true;
}
bool
AndroidNativeWindowTextureData::Lock(OpenMode)
{
// ANativeWindows can only be locked and unlocked a single time, after which
// we must wait until they receive ownership back from the host.
// Therefore we must only actually call ANativeWindow_lock() once per cycle.
if (!mIsLocked) {
int32_t r = ANativeWindow_lock(mNativeWindow, &mBuffer, nullptr);
if (r == -ENOMEM) {
return false;
} else if (r < 0) {
MOZ_CRASH("ANativeWindow_lock failed.");
}
mIsLocked = true;
}
return true;
}
void
AndroidNativeWindowTextureData::Unlock()
{
// The TextureClient may want to call Lock again before handing ownership
// to the host, so we cannot call ANativeWindow_unlockAndPost yet.
}
void
AndroidNativeWindowTextureData::Forget(LayersIPCChannel*)
{
MOZ_ASSERT(!mIsLocked, "ANativeWindow should not be released while locked.\n");
ANativeWindow_release(mNativeWindow);
mNativeWindow = nullptr;
java::SurfaceAllocator::DisposeSurface(mSurface);
mSurface = nullptr;
}
already_AddRefed<gfx::DrawTarget>
AndroidNativeWindowTextureData::BorrowDrawTarget()
{
const int bpp = (mFormat == gfx::SurfaceFormat::R5G6B5_UINT16) ? 2 : 4;
return gfx::Factory::CreateDrawTargetForData(
gfx::BackendType::SKIA,
static_cast<unsigned char*>(mBuffer.bits),
gfx::IntSize(mBuffer.width, mBuffer.height),
mBuffer.stride * bpp,
mFormat,
true);
}
void
AndroidNativeWindowTextureData::OnForwardedToHost()
{
if (mIsLocked) {
int32_t r = ANativeWindow_unlockAndPost(mNativeWindow);
if (r < 0) {
MOZ_CRASH("ANativeWindow_unlockAndPost failed\n.");
}
mIsLocked = false;
}
}
#endif // MOZ_WIDGET_ANDROID
} // namespace layers
} // namespace mozilla