зеркало из https://github.com/mozilla/gecko-dev.git
Bug 721741 - Add support for Flash on Android 4.0+ r=blassey
This commit is contained in:
Родитель
bbf92b6093
Коммит
ee323c2710
|
@ -138,6 +138,7 @@ endif
|
||||||
|
|
||||||
LOCAL_INCLUDES += \
|
LOCAL_INCLUDES += \
|
||||||
-DSK_BUILD_FOR_ANDROID_NDK \
|
-DSK_BUILD_FOR_ANDROID_NDK \
|
||||||
|
-I$(topsrcdir)/widget/android \
|
||||||
-I$(topsrcdir)/xpcom/base/ \
|
-I$(topsrcdir)/xpcom/base/ \
|
||||||
-I$(topsrcdir)/gfx/skia/include/core \
|
-I$(topsrcdir)/gfx/skia/include/core \
|
||||||
-I$(topsrcdir)/gfx/skia/include/config \
|
-I$(topsrcdir)/gfx/skia/include/config \
|
||||||
|
|
|
@ -306,7 +306,6 @@ anp_audio_start(ANPAudioTrack* s)
|
||||||
|
|
||||||
if (s->keepGoing) {
|
if (s->keepGoing) {
|
||||||
// we are already playing. Ignore.
|
// we are already playing. Ignore.
|
||||||
LOG("anp_audio_start called twice!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +358,14 @@ anp_audio_isStopped(ANPAudioTrack* s)
|
||||||
return s->isStopped;
|
return s->isStopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i) {
|
uint32_t
|
||||||
|
anp_audio_trackLatency(ANPAudioTrack* s) {
|
||||||
|
// Bug 721835
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitAudioTrackInterfaceV0(ANPAudioTrackInterfaceV0 *i) {
|
||||||
_assert(i->inSize == sizeof(*i));
|
_assert(i->inSize == sizeof(*i));
|
||||||
ASSIGN(i, newTrack);
|
ASSIGN(i, newTrack);
|
||||||
ASSIGN(i, deleteTrack);
|
ASSIGN(i, deleteTrack);
|
||||||
|
@ -368,3 +374,14 @@ void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i) {
|
||||||
ASSIGN(i, stop);
|
ASSIGN(i, stop);
|
||||||
ASSIGN(i, isStopped);
|
ASSIGN(i, isStopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitAudioTrackInterfaceV1(ANPAudioTrackInterfaceV1 *i) {
|
||||||
|
_assert(i->inSize == sizeof(*i));
|
||||||
|
ASSIGN(i, newTrack);
|
||||||
|
ASSIGN(i, deleteTrack);
|
||||||
|
ASSIGN(i, start);
|
||||||
|
ASSIGN(i, pause);
|
||||||
|
ASSIGN(i, stop);
|
||||||
|
ASSIGN(i, isStopped);
|
||||||
|
ASSIGN(i, trackLatency);
|
||||||
|
}
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#include "android_npapi.h"
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "android_npapi.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
#include "nsISupportsImpl.h"
|
#include "nsISupportsImpl.h"
|
||||||
|
|
||||||
|
@ -53,7 +53,8 @@
|
||||||
"!!!!!!!!!!!!!! %s not implemented %s, %d", \
|
"!!!!!!!!!!!!!! %s not implemented %s, %d", \
|
||||||
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
||||||
|
|
||||||
void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i);
|
void InitAudioTrackInterfaceV0(ANPAudioTrackInterfaceV0 *i);
|
||||||
|
void InitAudioTrackInterfaceV1(ANPAudioTrackInterfaceV1* i);
|
||||||
void InitBitmapInterface(ANPBitmapInterfaceV0 *i);
|
void InitBitmapInterface(ANPBitmapInterfaceV0 *i);
|
||||||
void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
|
void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
|
||||||
void InitEventInterface(ANPEventInterfaceV0 *i);
|
void InitEventInterface(ANPEventInterfaceV0 *i);
|
||||||
|
@ -63,5 +64,13 @@ void InitPaintInterface(ANPPaintInterfaceV0 *i);
|
||||||
void InitPathInterface(ANPPathInterfaceV0 *i);
|
void InitPathInterface(ANPPathInterfaceV0 *i);
|
||||||
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
|
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
|
||||||
void InitSystemInterface(ANPSystemInterfaceV0 *i);
|
void InitSystemInterface(ANPSystemInterfaceV0 *i);
|
||||||
|
void InitSystemInterfaceV1(ANPSystemInterfaceV1 *i);
|
||||||
|
void InitSystemInterfaceV2(ANPSystemInterfaceV2 *i);
|
||||||
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i);
|
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *i);
|
||||||
void InitWindowInterface(ANPWindowInterfaceV0 *i);
|
void InitWindowInterface(ANPWindowInterfaceV0 *i);
|
||||||
|
void InitWindowInterfaceV1(ANPWindowInterfaceV1 *i);
|
||||||
|
void InitWindowInterfaceV2(ANPWindowInterfaceV2 *i);
|
||||||
|
void InitVideoInterfaceV0(ANPVideoInterfaceV0 *i);
|
||||||
|
void InitVideoInterfaceV1(ANPVideoInterfaceV1 *i);
|
||||||
|
void InitOpenGLInterface(ANPOpenGLInterfaceV0 *i);
|
||||||
|
void InitNativeWindowInterface(ANPNativeWindowInterfaceV0 *i);
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Android NPAPI support code
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* the Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// must include config.h first for webkit to fiddle with new/delete
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "AndroidBridge.h"
|
||||||
|
#include "AndroidMediaLayer.h"
|
||||||
|
#include "ANPBase.h"
|
||||||
|
#include "nsIPluginInstanceOwner.h"
|
||||||
|
#include "nsPluginInstanceOwner.h"
|
||||||
|
#include "nsNPAPIPluginInstance.h"
|
||||||
|
#include "gfxRect.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||||
|
#define ASSIGN(obj, name) (obj)->name = anp_native_window_##name
|
||||||
|
|
||||||
|
static ANPNativeWindow anp_native_window_acquireNativeWindow(NPP instance) {
|
||||||
|
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner;
|
||||||
|
if (NS_FAILED(pinst->GetOwner((nsIPluginInstanceOwner**)&owner))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ANPNativeWindow window = owner->Layer()->GetNativeWindowForContent();
|
||||||
|
owner->Invalidate();
|
||||||
|
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anp_native_window_invertPluginContent(NPP instance, bool isContentInverted) {
|
||||||
|
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner;
|
||||||
|
if (NS_FAILED(pinst->GetOwner((nsIPluginInstanceOwner**)&owner))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
owner->Layer()->SetInverted(isContentInverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InitNativeWindowInterface(ANPNativeWindowInterfaceV0* i) {
|
||||||
|
ASSIGN(i, acquireNativeWindow);
|
||||||
|
ASSIGN(i, invertPluginContent);
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* The Original Code is Android NPAPI support code
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* the Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "AndroidBridge.h"
|
||||||
|
#include "ANPBase.h"
|
||||||
|
#include "GLContextProvider.h"
|
||||||
|
#include "nsNPAPIPluginInstance.h"
|
||||||
|
|
||||||
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||||
|
#define ASSIGN(obj, name) (obj)->name = anp_opengl_##name
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
using namespace mozilla::gl;
|
||||||
|
|
||||||
|
static ANPEGLContext anp_opengl_acquireContext(NPP inst) {
|
||||||
|
// Bug 687267
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ANPTextureInfo anp_opengl_lockTexture(NPP instance) {
|
||||||
|
ANPTextureInfo info = { 0, 0, 0, 0 };
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anp_opengl_releaseTexture(NPP instance, const ANPTextureInfo* info) {
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anp_opengl_invertPluginContent(NPP instance, bool isContentInverted) {
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void InitOpenGLInterface(ANPOpenGLInterfaceV0* i) {
|
||||||
|
ASSIGN(i, acquireContext);
|
||||||
|
ASSIGN(i, lockTexture);
|
||||||
|
ASSIGN(i, releaseTexture);
|
||||||
|
ASSIGN(i, invertPluginContent);
|
||||||
|
}
|
|
@ -62,6 +62,12 @@ anp_system_getApplicationDataDirectory()
|
||||||
return dir;
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
anp_system_getApplicationDataDirectory(NPP instance)
|
||||||
|
{
|
||||||
|
return anp_system_getApplicationDataDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
||||||
{
|
{
|
||||||
LOG("%s", __PRETTY_FUNCTION__);
|
LOG("%s", __PRETTY_FUNCTION__);
|
||||||
|
@ -88,8 +94,27 @@ jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
||||||
return reinterpret_cast<jclass>(obj);
|
return reinterpret_cast<jclass>(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void anp_system_setPowerState(NPP instance, ANPPowerState powerState)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
void InitSystemInterface(ANPSystemInterfaceV0 *i) {
|
void InitSystemInterface(ANPSystemInterfaceV0 *i) {
|
||||||
_assert(i->inSize == sizeof(*i));
|
_assert(i->inSize == sizeof(*i));
|
||||||
ASSIGN(i, getApplicationDataDirectory);
|
ASSIGN(i, getApplicationDataDirectory);
|
||||||
ASSIGN(i, loadJavaClass);
|
ASSIGN(i, loadJavaClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitSystemInterfaceV1(ANPSystemInterfaceV1 *i) {
|
||||||
|
_assert(i->inSize == sizeof(*i));
|
||||||
|
ASSIGN(i, getApplicationDataDirectory);
|
||||||
|
ASSIGN(i, loadJavaClass);
|
||||||
|
ASSIGN(i, setPowerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitSystemInterfaceV2(ANPSystemInterfaceV2 *i) {
|
||||||
|
_assert(i->inSize == sizeof(*i));
|
||||||
|
ASSIGN(i, getApplicationDataDirectory);
|
||||||
|
ASSIGN(i, loadJavaClass);
|
||||||
|
ASSIGN(i, setPowerState);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/* The Original Code is Android NPAPI support code
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* the Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "ANPBase.h"
|
||||||
|
#include "AndroidMediaLayer.h"
|
||||||
|
#include "nsIPluginInstanceOwner.h"
|
||||||
|
#include "nsPluginInstanceOwner.h"
|
||||||
|
#include "nsNPAPIPluginInstance.h"
|
||||||
|
#include "gfxRect.h"
|
||||||
|
|
||||||
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||||
|
#define ASSIGN(obj, name) (obj)->name = anp_video_##name
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
static AndroidMediaLayer* GetLayerForInstance(NPP instance) {
|
||||||
|
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner;
|
||||||
|
if (NS_FAILED(pinst->GetOwner((nsIPluginInstanceOwner**)&owner))) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner->Layer();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Invalidate(NPP instance) {
|
||||||
|
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner;
|
||||||
|
if (NS_FAILED(pinst->GetOwner((nsIPluginInstanceOwner**)&owner)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
owner->Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
static ANPNativeWindow anp_video_acquireNativeWindow(NPP instance) {
|
||||||
|
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||||
|
if (!layer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return layer->RequestNativeWindowForVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anp_video_setWindowDimensions(NPP instance, const ANPNativeWindow window,
|
||||||
|
const ANPRectF* dimensions) {
|
||||||
|
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||||
|
if (!layer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gfxRect rect(dimensions->left, dimensions->top,
|
||||||
|
dimensions->right - dimensions->left,
|
||||||
|
dimensions->bottom - dimensions->top);
|
||||||
|
|
||||||
|
layer->SetNativeWindowDimensions(window, rect);
|
||||||
|
Invalidate(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void anp_video_releaseNativeWindow(NPP instance, ANPNativeWindow window) {
|
||||||
|
AndroidMediaLayer* layer = GetLayerForInstance(instance);
|
||||||
|
if (!layer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layer->ReleaseNativeWindowForVideo(window);
|
||||||
|
Invalidate(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void anp_video_setFramerateCallback(NPP instance, const ANPNativeWindow window, ANPVideoFrameCallbackProc callback) {
|
||||||
|
// Bug 722682
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void InitVideoInterfaceV0(ANPVideoInterfaceV0* i) {
|
||||||
|
ASSIGN(i, acquireNativeWindow);
|
||||||
|
ASSIGN(i, setWindowDimensions);
|
||||||
|
ASSIGN(i, releaseNativeWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitVideoInterfaceV1(ANPVideoInterfaceV1* i) {
|
||||||
|
ASSIGN(i, acquireNativeWindow);
|
||||||
|
ASSIGN(i, setWindowDimensions);
|
||||||
|
ASSIGN(i, releaseNativeWindow);
|
||||||
|
ASSIGN(i, setFramerateCallback);
|
||||||
|
}
|
|
@ -39,10 +39,16 @@
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "ANPBase.h"
|
#include "ANPBase.h"
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
#include "AndroidBridge.h"
|
||||||
|
#include "nsNPAPIPluginInstance.h"
|
||||||
|
#include "nsIPluginInstanceOwner.h"
|
||||||
|
#include "nsPluginInstanceOwner.h"
|
||||||
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||||
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
|
#define ASSIGN(obj, name) (obj)->name = anp_window_##name
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
void
|
void
|
||||||
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
|
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
|
||||||
{
|
{
|
||||||
|
@ -79,6 +85,32 @@ anp_window_requestCenterFitZoom(NPP instance)
|
||||||
NOT_IMPLEMENTED();
|
NOT_IMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ANPRectI
|
||||||
|
anp_window_visibleRect(NPP instance)
|
||||||
|
{
|
||||||
|
ANPRectI rect = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
|
||||||
|
|
||||||
|
nsPluginInstanceOwner* owner;
|
||||||
|
if (NS_FAILED(pinst->GetOwner((nsIPluginInstanceOwner**)&owner))) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIntRect visibleRect = owner->GetVisibleRect();
|
||||||
|
rect.left = visibleRect.x;
|
||||||
|
rect.top = visibleRect.y;
|
||||||
|
rect.right = visibleRect.x + visibleRect.width;
|
||||||
|
rect.bottom = visibleRect.y + visibleRect.height;
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void anp_window_requestFullScreenOrientation(NPP instance, ANPScreenOrientation orientation)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
void InitWindowInterface(ANPWindowInterfaceV0 *i) {
|
void InitWindowInterface(ANPWindowInterfaceV0 *i) {
|
||||||
_assert(i->inSize == sizeof(*i));
|
_assert(i->inSize == sizeof(*i));
|
||||||
ASSIGN(i, setVisibleRects);
|
ASSIGN(i, setVisibleRects);
|
||||||
|
@ -89,3 +121,26 @@ void InitWindowInterface(ANPWindowInterfaceV0 *i) {
|
||||||
ASSIGN(i, requestCenterFitZoom);
|
ASSIGN(i, requestCenterFitZoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InitWindowInterfaceV1(ANPWindowInterfaceV1 *i) {
|
||||||
|
_assert(i->inSize == sizeof(*i));
|
||||||
|
ASSIGN(i, setVisibleRects);
|
||||||
|
ASSIGN(i, clearVisibleRects);
|
||||||
|
ASSIGN(i, showKeyboard);
|
||||||
|
ASSIGN(i, requestFullScreen);
|
||||||
|
ASSIGN(i, exitFullScreen);
|
||||||
|
ASSIGN(i, requestCenterFitZoom);
|
||||||
|
ASSIGN(i, visibleRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitWindowInterfaceV2(ANPWindowInterfaceV2 *i) {
|
||||||
|
_assert(i->inSize == sizeof(*i));
|
||||||
|
ASSIGN(i, setVisibleRects);
|
||||||
|
ASSIGN(i, clearVisibleRects);
|
||||||
|
ASSIGN(i, showKeyboard);
|
||||||
|
ASSIGN(i, requestFullScreen);
|
||||||
|
ASSIGN(i, exitFullScreen);
|
||||||
|
ASSIGN(i, requestCenterFitZoom);
|
||||||
|
ASSIGN(i, visibleRect);
|
||||||
|
ASSIGN(i, requestFullScreenOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,17 @@ CPPSRCS += ANPAudio.cpp \
|
||||||
ANPWindow.cpp \
|
ANPWindow.cpp \
|
||||||
ANPBitmap.cpp \
|
ANPBitmap.cpp \
|
||||||
ANPLog.cpp \
|
ANPLog.cpp \
|
||||||
|
ANPNativeWindow.cpp \
|
||||||
ANPSurface.cpp \
|
ANPSurface.cpp \
|
||||||
|
ANPVideo.cpp \
|
||||||
|
ANPOpenGL.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
LOCAL_INCLUDES += \
|
LOCAL_INCLUDES += \
|
||||||
|
-I$(topsrcdir)/widget/android \
|
||||||
-I$(topsrcdir)/dom/plugins/base \
|
-I$(topsrcdir)/dom/plugins/base \
|
||||||
-I$(topsrcdir)/dom/plugins/base/android/include \
|
-I$(topsrcdir)/dom/plugins/base/android/include \
|
||||||
|
-I$(topsrcdir)/gfx/gl \
|
||||||
$(MOZ_CAIRO_CFLAGS) \
|
$(MOZ_CAIRO_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,9 @@
|
||||||
#define android_npapi_H
|
#define android_npapi_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "npapi.h"
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
#include "npapi.h"
|
||||||
|
#include "GLDefs.h"
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// General types
|
// General types
|
||||||
|
@ -120,6 +121,16 @@ typedef uint32_t ANPMatrixFlag;
|
||||||
#define kSystemInterfaceV0_ANPGetValue ((NPNVariable)1010)
|
#define kSystemInterfaceV0_ANPGetValue ((NPNVariable)1010)
|
||||||
#define kEventInterfaceV0_ANPGetValue ((NPNVariable)1011)
|
#define kEventInterfaceV0_ANPGetValue ((NPNVariable)1011)
|
||||||
|
|
||||||
|
#define kAudioTrackInterfaceV1_ANPGetValue ((NPNVariable)1012)
|
||||||
|
#define kOpenGLInterfaceV0_ANPGetValue ((NPNVariable)1013)
|
||||||
|
#define kWindowInterfaceV1_ANPGetValue ((NPNVariable)1014)
|
||||||
|
#define kVideoInterfaceV0_ANPGetValue ((NPNVariable)1015)
|
||||||
|
#define kSystemInterfaceV1_ANPGetValue ((NPNVariable)1016)
|
||||||
|
#define kSystemInterfaceV2_ANPGetValue ((NPNVariable)1017)
|
||||||
|
#define kWindowInterfaceV2_ANPGetValue ((NPNVariable)1018)
|
||||||
|
#define kNativeWindowInterfaceV0_ANPGetValue ((NPNVariable)1019)
|
||||||
|
#define kVideoInterfaceV1_ANPGetValue ((NPNVariable)1020)
|
||||||
|
|
||||||
/** queries for the drawing models supported on this device.
|
/** queries for the drawing models supported on this device.
|
||||||
|
|
||||||
NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)
|
NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)
|
||||||
|
@ -180,6 +191,7 @@ enum ANPDrawingModels {
|
||||||
surface object.
|
surface object.
|
||||||
*/
|
*/
|
||||||
kSurface_ANPDrawingModel = 1 << 1,
|
kSurface_ANPDrawingModel = 1 << 1,
|
||||||
|
kOpenGL_ANPDrawingModel = 1 << 2,
|
||||||
};
|
};
|
||||||
typedef int32_t ANPDrawingModel;
|
typedef int32_t ANPDrawingModel;
|
||||||
|
|
||||||
|
@ -678,6 +690,25 @@ struct ANPWindowInterfaceV0 : ANPInterface {
|
||||||
void (*requestCenterFitZoom)(NPP instance);
|
void (*requestCenterFitZoom)(NPP instance);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ANPWindowInterfaceV1 : ANPWindowInterfaceV0 {
|
||||||
|
/** Returns a rectangle representing the visible area of the plugin on
|
||||||
|
screen. The coordinates are relative to the size of the plugin in the
|
||||||
|
document and therefore will never be negative or exceed the plugin's size.
|
||||||
|
*/
|
||||||
|
ANPRectI (*visibleRect)(NPP instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int32_t ANPScreenOrientation;
|
||||||
|
|
||||||
|
struct ANPWindowInterfaceV2 : ANPWindowInterfaceV1 {
|
||||||
|
/** Called when the plugin wants to specify a particular screen orientation
|
||||||
|
when entering into full screen mode. The orientation must be set prior
|
||||||
|
to entering into full screen. After entering full screen any subsequent
|
||||||
|
changes will be updated the next time the plugin goes full screen.
|
||||||
|
*/
|
||||||
|
void (*requestFullScreenOrientation)(NPP instance, ANPScreenOrientation orientation);
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
enum ANPSampleFormats {
|
enum ANPSampleFormats {
|
||||||
|
@ -762,6 +793,12 @@ struct ANPAudioTrackInterfaceV0 : ANPInterface {
|
||||||
bool (*isStopped)(ANPAudioTrack*);
|
bool (*isStopped)(ANPAudioTrack*);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ANPAudioTrackInterfaceV1 : ANPAudioTrackInterfaceV0 {
|
||||||
|
/** Returns the track's latency in milliseconds. */
|
||||||
|
uint32_t (*trackLatency)(ANPAudioTrack*);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// DEFINITION OF VALUES PASSED THROUGH NPP_HandleEvent
|
// DEFINITION OF VALUES PASSED THROUGH NPP_HandleEvent
|
||||||
|
|
||||||
|
@ -922,12 +959,16 @@ struct ANPEvent {
|
||||||
// use based on the value in model
|
// use based on the value in model
|
||||||
union {
|
union {
|
||||||
ANPBitmap bitmap;
|
ANPBitmap bitmap;
|
||||||
|
struct {
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
} surfaceSize;
|
||||||
} data;
|
} data;
|
||||||
} draw;
|
} draw;
|
||||||
int32_t other[8];
|
|
||||||
} data;
|
} data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ANPEventInterfaceV0 : ANPInterface {
|
struct ANPEventInterfaceV0 : ANPInterface {
|
||||||
/** Post a copy of the specified event to the plugin. The event will be
|
/** Post a copy of the specified event to the plugin. The event will be
|
||||||
delivered to the plugin in its main thread (the thread that receives
|
delivered to the plugin in its main thread (the thread that receives
|
||||||
|
@ -976,4 +1017,117 @@ typedef uint32_t uint32;
|
||||||
typedef int16_t int16;
|
typedef int16_t int16;
|
||||||
typedef uint16_t uint16;
|
typedef uint16_t uint16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO should we not use EGL and GL data types for ABI safety?
|
||||||
|
*/
|
||||||
|
struct ANPTextureInfo {
|
||||||
|
GLuint textureId;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
GLenum internalFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void* ANPEGLContext;
|
||||||
|
|
||||||
|
struct ANPOpenGLInterfaceV0 : ANPInterface {
|
||||||
|
ANPEGLContext (*acquireContext)(NPP instance);
|
||||||
|
|
||||||
|
ANPTextureInfo (*lockTexture)(NPP instance);
|
||||||
|
|
||||||
|
void (*releaseTexture)(NPP instance, const ANPTextureInfo*);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invert the contents of the plugin on the y-axis.
|
||||||
|
* default is to not be inverted (i.e. use OpenGL coordinates)
|
||||||
|
*/
|
||||||
|
void (*invertPluginContent)(NPP instance, bool isContentInverted);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ANPPowerStates {
|
||||||
|
kDefault_ANPPowerState = 0,
|
||||||
|
kScreenOn_ANPPowerState = 1
|
||||||
|
};
|
||||||
|
typedef int32_t ANPPowerState;
|
||||||
|
|
||||||
|
struct ANPSystemInterfaceV1 : ANPSystemInterfaceV0 {
|
||||||
|
void (*setPowerState)(NPP instance, ANPPowerState powerState);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANPSystemInterfaceV2 : ANPInterface {
|
||||||
|
/** Return the path name for the current Application's plugin data directory,
|
||||||
|
or NULL if not supported. This directory will change depending on whether
|
||||||
|
or not the plugin is found within an incognito tab.
|
||||||
|
*/
|
||||||
|
const char* (*getApplicationDataDirectory)(NPP instance);
|
||||||
|
|
||||||
|
// redeclaration of existing features
|
||||||
|
jclass (*loadJavaClass)(NPP instance, const char* className);
|
||||||
|
void (*setPowerState)(NPP instance, ANPPowerState powerState);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void* ANPNativeWindow;
|
||||||
|
|
||||||
|
struct ANPVideoInterfaceV0 : ANPInterface {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new native window to be used for rendering video content.
|
||||||
|
*
|
||||||
|
* Subsequent calls will produce new windows, but may also return NULL after
|
||||||
|
* n attempts if the browser has reached it's limit. Further, if the browser
|
||||||
|
* is unable to acquire the window quickly it may also return NULL in order
|
||||||
|
* to not prevent the plugin from executing. A subsequent call will then
|
||||||
|
* return the window if it is avaiable.
|
||||||
|
*
|
||||||
|
* NOTE: The hardware may fail if you try to decode more than the allowable
|
||||||
|
* number of videos supported on that device.
|
||||||
|
*/
|
||||||
|
ANPNativeWindow (*acquireNativeWindow)(NPP instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the rectangle that specifies where the video content is to be drawn.
|
||||||
|
* The dimensions are in document space. Further, if the rect is NULL the
|
||||||
|
* browser will not attempt to draw the window, therefore do not set the
|
||||||
|
* dimensions until you queue the first buffer in the window.
|
||||||
|
*/
|
||||||
|
void (*setWindowDimensions)(NPP instance, const ANPNativeWindow window, const ANPRectF* dimensions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
void (*releaseNativeWindow)(NPP instance, ANPNativeWindow window);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Called to notify the plugin that a video frame has been composited by the
|
||||||
|
* browser for display. This will be called in a separate thread and as such
|
||||||
|
* you cannot call releaseNativeWindow from the callback.
|
||||||
|
*
|
||||||
|
* The timestamp is in nanoseconds, and is monotonically increasing.
|
||||||
|
*/
|
||||||
|
typedef void (*ANPVideoFrameCallbackProc)(ANPNativeWindow* window, int64_t timestamp);
|
||||||
|
|
||||||
|
struct ANPVideoInterfaceV1 : ANPVideoInterfaceV0 {
|
||||||
|
/** Set a callback to be notified when an ANPNativeWindow is composited by
|
||||||
|
* the browser.
|
||||||
|
*/
|
||||||
|
void (*setFramerateCallback)(NPP instance, const ANPNativeWindow window, ANPVideoFrameCallbackProc);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ANPNativeWindowInterfaceV0 : ANPInterface {
|
||||||
|
/**
|
||||||
|
* Constructs a new native window to be used for rendering plugin content.
|
||||||
|
*
|
||||||
|
* Subsequent calls will return the original constructed window. Further, if
|
||||||
|
* the browser is unable to acquire the window quickly it may return NULL in
|
||||||
|
* order to not block the plugin indefinitely. A subsequent call will then
|
||||||
|
* return the window if it is available.
|
||||||
|
*/
|
||||||
|
ANPNativeWindow (*acquireNativeWindow)(NPP instance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invert the contents of the plugin on the y-axis.
|
||||||
|
* default is to not be inverted (e.g. use OpenGL coordinates)
|
||||||
|
*/
|
||||||
|
void (*invertPluginContent)(NPP instance, bool isContentInverted);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -132,9 +132,10 @@ using mozilla::plugins::PluginModuleParent;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "android_npapi.h"
|
||||||
#include "ANPBase.h"
|
#include "ANPBase.h"
|
||||||
#include "AndroidBridge.h"
|
#include "AndroidBridge.h"
|
||||||
#include <android/log.h>
|
|
||||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2348,7 +2349,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
case kAudioTrackInterfaceV0_ANPGetValue: {
|
case kAudioTrackInterfaceV0_ANPGetValue: {
|
||||||
LOG("get audio interface");
|
LOG("get audio interface");
|
||||||
ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
|
ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
|
||||||
InitAudioTrackInterface(i);
|
InitAudioTrackInterfaceV0(i);
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2363,7 +2364,6 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
LOG("get system interface");
|
LOG("get system interface");
|
||||||
ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
|
ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
|
||||||
InitSystemInterface(i);
|
InitSystemInterface(i);
|
||||||
LOG("done system interface");
|
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2395,6 +2395,71 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||||
*i = reinterpret_cast<int32_t>(ret);
|
*i = reinterpret_cast<int32_t>(ret);
|
||||||
return NPERR_NO_ERROR;
|
return NPERR_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kAudioTrackInterfaceV1_ANPGetValue: {
|
||||||
|
LOG("get audio interface v1");
|
||||||
|
ANPAudioTrackInterfaceV1 *i = (ANPAudioTrackInterfaceV1 *) result;
|
||||||
|
InitAudioTrackInterfaceV1(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kNativeWindowInterfaceV0_ANPGetValue: {
|
||||||
|
LOG("get native window interface v0");
|
||||||
|
ANPNativeWindowInterfaceV0* i = (ANPNativeWindowInterfaceV0 *) result;
|
||||||
|
InitNativeWindowInterface(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kOpenGLInterfaceV0_ANPGetValue: {
|
||||||
|
LOG("get openGL interface");
|
||||||
|
ANPOpenGLInterfaceV0 *i = (ANPOpenGLInterfaceV0*) result;
|
||||||
|
InitOpenGLInterface(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kWindowInterfaceV1_ANPGetValue: {
|
||||||
|
LOG("get Window interface V1");
|
||||||
|
ANPWindowInterfaceV1 *i = (ANPWindowInterfaceV1 *) result;
|
||||||
|
InitWindowInterfaceV1(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kWindowInterfaceV2_ANPGetValue: {
|
||||||
|
LOG("get Window interface V2");
|
||||||
|
ANPWindowInterfaceV2 *i = (ANPWindowInterfaceV2 *) result;
|
||||||
|
InitWindowInterfaceV2(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kVideoInterfaceV0_ANPGetValue: {
|
||||||
|
LOG("get video interface");
|
||||||
|
ANPVideoInterfaceV0 *i = (ANPVideoInterfaceV0*) result;
|
||||||
|
InitVideoInterfaceV0(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kVideoInterfaceV1_ANPGetValue: {
|
||||||
|
LOG("get video interface");
|
||||||
|
ANPVideoInterfaceV1 *i = (ANPVideoInterfaceV1*) result;
|
||||||
|
InitVideoInterfaceV1(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
case kSystemInterfaceV1_ANPGetValue: {
|
||||||
|
LOG("get system interface v1");
|
||||||
|
ANPSystemInterfaceV1* i = reinterpret_cast<ANPSystemInterfaceV1*>(result);
|
||||||
|
InitSystemInterfaceV1(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
case kSystemInterfaceV2_ANPGetValue: {
|
||||||
|
LOG("get system interface v2");
|
||||||
|
ANPSystemInterfaceV2* i = reinterpret_cast<ANPSystemInterfaceV2*>(result);
|
||||||
|
InitSystemInterfaceV2(i);
|
||||||
|
return NPERR_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// we no longer hand out any XPCOM objects
|
// we no longer hand out any XPCOM objects
|
||||||
|
|
|
@ -152,6 +152,8 @@ public:
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
PRUint32 GetANPDrawingModel() { return mANPDrawingModel; }
|
PRUint32 GetANPDrawingModel() { return mANPDrawingModel; }
|
||||||
void SetANPDrawingModel(PRUint32 aModel);
|
void SetANPDrawingModel(PRUint32 aModel);
|
||||||
|
|
||||||
|
// This stuff is for kSurface_ANPDrawingModel
|
||||||
void* GetJavaSurface();
|
void* GetJavaSurface();
|
||||||
void SetJavaSurface(void* aSurface);
|
void SetJavaSurface(void* aSurface);
|
||||||
void RequestJavaSurface();
|
void RequestJavaSurface();
|
||||||
|
|
|
@ -120,6 +120,7 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||||
#include "ANPBase.h"
|
#include "ANPBase.h"
|
||||||
#include "android_npapi.h"
|
#include "android_npapi.h"
|
||||||
#include "AndroidBridge.h"
|
#include "AndroidBridge.h"
|
||||||
|
#include "AndroidMediaLayer.h"
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
@ -331,8 +332,9 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||||
mWaitingForPaint = false;
|
mWaitingForPaint = false;
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
mPluginViewAdded = false;
|
mOnScreen = false;
|
||||||
mLastPluginRect = gfxRect(0, 0, 0, 0);
|
mInverted = false;
|
||||||
|
mLayer = new AndroidMediaLayer();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +390,13 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
||||||
mPluginWindow = nsnull;
|
mPluginWindow = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
if (mLayer) {
|
||||||
|
delete mLayer;
|
||||||
|
mLayer = nsnull;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mInstance) {
|
if (mInstance) {
|
||||||
mInstance->InvalidateOwner();
|
mInstance->InvalidateOwner();
|
||||||
}
|
}
|
||||||
|
@ -1666,6 +1675,43 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
|
||||||
|
void nsPluginInstanceOwner::SendSize(int width, int height)
|
||||||
|
{
|
||||||
|
if (!mInstance)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||||
|
|
||||||
|
if (model != kOpenGL_ANPDrawingModel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ANPEvent event;
|
||||||
|
event.inSize = sizeof(ANPEvent);
|
||||||
|
event.eventType = kDraw_ANPEventType;
|
||||||
|
event.data.draw.model = kOpenGL_ANPDrawingModel;
|
||||||
|
event.data.draw.data.surfaceSize.width = width;
|
||||||
|
event.data.draw.data.surfaceSize.height = height;
|
||||||
|
|
||||||
|
mInstance->HandleEvent(&event, nsnull);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsPluginInstanceOwner::SendOnScreenEvent(bool onScreen)
|
||||||
|
{
|
||||||
|
if (!mInstance)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((onScreen && !mOnScreen) || (!onScreen && mOnScreen)) {
|
||||||
|
ANPEvent event;
|
||||||
|
event.inSize = sizeof(ANPEvent);
|
||||||
|
event.eventType = kLifecycle_ANPEventType;
|
||||||
|
event.data.lifecycle.action = onScreen ? kOnScreen_ANPLifecycleAction : kOffScreen_ANPLifecycleAction;
|
||||||
|
mInstance->HandleEvent(&event, nsnull);
|
||||||
|
|
||||||
|
mOnScreen = onScreen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||||
{
|
{
|
||||||
void* javaSurface = mInstance->GetJavaSurface();
|
void* javaSurface = mInstance->GetJavaSurface();
|
||||||
|
@ -1674,11 +1720,6 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aRect.IsEqualEdges(mLastPluginRect)) {
|
|
||||||
// Already added and in position, no work to do
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
JNIEnv* env = GetJNIForThread();
|
JNIEnv* env = GetJNIForThread();
|
||||||
if (!env)
|
if (!env)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1721,26 +1762,16 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||||
aRect.height);
|
aRect.height);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!mPluginViewAdded) {
|
SendOnScreenEvent(true);
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kLifecycle_ANPEventType;
|
|
||||||
event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
|
|
||||||
mInstance->HandleEvent(&event, nsnull);
|
|
||||||
|
|
||||||
mPluginViewAdded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsPluginInstanceOwner::RemovePluginView()
|
void nsPluginInstanceOwner::RemovePluginView()
|
||||||
{
|
{
|
||||||
if (!mInstance || !mObjectFrame | !mPluginViewAdded)
|
if (!mInstance || !mObjectFrame | !mOnScreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mPluginViewAdded = false;
|
|
||||||
|
|
||||||
void* surface = mInstance->GetJavaSurface();
|
void* surface = mInstance->GetJavaSurface();
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return;
|
return;
|
||||||
|
@ -1756,13 +1787,17 @@ void nsPluginInstanceOwner::RemovePluginView()
|
||||||
"removePluginView",
|
"removePluginView",
|
||||||
"(Landroid/view/View;)V");
|
"(Landroid/view/View;)V");
|
||||||
env->CallStaticVoidMethod(cls, method, surface);
|
env->CallStaticVoidMethod(cls, method, surface);
|
||||||
|
SendOnScreenEvent(false);
|
||||||
ANPEvent event;
|
|
||||||
event.inSize = sizeof(ANPEvent);
|
|
||||||
event.eventType = kLifecycle_ANPEventType;
|
|
||||||
event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
|
|
||||||
mInstance->HandleEvent(&event, nsnull);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsPluginInstanceOwner::Invalidate() {
|
||||||
|
NPRect rect;
|
||||||
|
rect.left = rect.top = 0;
|
||||||
|
rect.right = mPluginWindow->width;
|
||||||
|
rect.bottom = mPluginWindow->height;
|
||||||
|
InvalidateRect(&rect);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
||||||
|
@ -2787,7 +2822,15 @@ nsPluginInstanceOwner::PrepareToStop(bool aDelayedStop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
RemovePluginView();
|
|
||||||
|
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||||
|
if (model == kSurface_ANPDrawingModel) {
|
||||||
|
RemovePluginView();
|
||||||
|
} else if (model == kOpenGL_ANPDrawingModel && mLayer) {
|
||||||
|
delete mLayer;
|
||||||
|
mLayer = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Unregister scroll position listeners
|
// Unregister scroll position listeners
|
||||||
|
@ -2899,15 +2942,21 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||||
|
|
||||||
if (model == kSurface_ANPDrawingModel) {
|
if (model == kSurface_ANPDrawingModel) {
|
||||||
if (!AddPluginView(aFrameRect)) {
|
if (!AddPluginView(aFrameRect)) {
|
||||||
NPRect rect;
|
Invalidate();
|
||||||
rect.left = rect.top = 0;
|
|
||||||
rect.right = aFrameRect.width;
|
|
||||||
rect.bottom = aFrameRect.height;
|
|
||||||
InvalidateRect(&rect);
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model == kOpenGL_ANPDrawingModel) {
|
||||||
|
// FIXME: this is gross
|
||||||
|
float zoomLevel = aFrameRect.width / (float)mPluginWindow->width;
|
||||||
|
mLayer->UpdatePosition(aFrameRect, zoomLevel);
|
||||||
|
|
||||||
|
SendOnScreenEvent(true);
|
||||||
|
SendSize((int)aFrameRect.width, (int)aFrameRect.height);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (model != kBitmap_ANPDrawingModel)
|
if (model != kBitmap_ANPDrawingModel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3598,8 +3647,16 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow)
|
||||||
} else {
|
} else {
|
||||||
mPluginWindow->clipRect.right = 0;
|
mPluginWindow->clipRect.right = 0;
|
||||||
mPluginWindow->clipRect.bottom = 0;
|
mPluginWindow->clipRect.bottom = 0;
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#if 0 //MOZ_WIDGET_ANDROID
|
||||||
RemovePluginView();
|
if (mInstance) {
|
||||||
|
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||||
|
|
||||||
|
if (model == kSurface_ANPDrawingModel) {
|
||||||
|
RemovePluginView();
|
||||||
|
} else if (model == kOpenGL_ANPDrawingModel) {
|
||||||
|
HidePluginLayer();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,6 +94,12 @@ class gfxXlibSurface;
|
||||||
#include <os2.h>
|
#include <os2.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
|
namespace mozilla {
|
||||||
|
class AndroidMediaLayer;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// X.h defines KeyPress
|
// X.h defines KeyPress
|
||||||
#ifdef KeyPress
|
#ifdef KeyPress
|
||||||
#undef KeyPress
|
#undef KeyPress
|
||||||
|
@ -298,6 +304,26 @@ public:
|
||||||
|
|
||||||
bool UseAsyncRendering();
|
bool UseAsyncRendering();
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
nsIntRect GetVisibleRect() {
|
||||||
|
return nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInverted(bool aInverted) {
|
||||||
|
mInverted = aInverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Inverted() {
|
||||||
|
return mInverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
mozilla::AndroidMediaLayer* Layer() {
|
||||||
|
return mLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Invalidate();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
|
// return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
|
||||||
|
@ -310,10 +336,17 @@ private:
|
||||||
|
|
||||||
void FixUpURLS(const nsString &name, nsAString &value);
|
void FixUpURLS(const nsString &name, nsAString &value);
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
|
void SendSize(int width, int height);
|
||||||
|
void SendOnScreenEvent(bool onScreen);
|
||||||
|
|
||||||
bool AddPluginView(const gfxRect& aRect);
|
bool AddPluginView(const gfxRect& aRect);
|
||||||
void RemovePluginView();
|
void RemovePluginView();
|
||||||
bool mPluginViewAdded;
|
|
||||||
gfxRect mLastPluginRect;
|
bool mOnScreen;
|
||||||
|
bool mInverted;
|
||||||
|
|
||||||
|
// For kOpenGL_ANPDrawingModel
|
||||||
|
mozilla::AndroidMediaLayer *mLayer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsPluginNativeWindow *mPluginWindow;
|
nsPluginNativeWindow *mPluginWindow;
|
||||||
|
|
|
@ -1729,7 +1729,6 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||||
// The matrix includes the frame's position, so we need to transform
|
// The matrix includes the frame's position, so we need to transform
|
||||||
// from 0,0 to get the correct coordinates.
|
// from 0,0 to get the correct coordinates.
|
||||||
frameGfxRect.MoveTo(0, 0);
|
frameGfxRect.MoveTo(0, 0);
|
||||||
matrix2d.NudgeToIntegers();
|
|
||||||
|
|
||||||
mInstanceOwner->Paint(ctx, matrix2d.Transform(frameGfxRect), dirtyGfxRect);
|
mInstanceOwner->Paint(ctx, matrix2d.Transform(frameGfxRect), dirtyGfxRect);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -40,13 +40,16 @@
|
||||||
|
|
||||||
package org.mozilla.gecko;
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.gfx.BufferedCairoImage;
|
||||||
import org.mozilla.gecko.gfx.FloatSize;
|
import org.mozilla.gecko.gfx.FloatSize;
|
||||||
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
|
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
|
||||||
import org.mozilla.gecko.gfx.IntSize;
|
import org.mozilla.gecko.gfx.IntSize;
|
||||||
|
import org.mozilla.gecko.gfx.Layer;
|
||||||
import org.mozilla.gecko.gfx.LayerController;
|
import org.mozilla.gecko.gfx.LayerController;
|
||||||
import org.mozilla.gecko.gfx.LayerView;
|
import org.mozilla.gecko.gfx.LayerView;
|
||||||
import org.mozilla.gecko.gfx.PlaceholderLayerClient;
|
import org.mozilla.gecko.gfx.PlaceholderLayerClient;
|
||||||
import org.mozilla.gecko.gfx.RectUtils;
|
import org.mozilla.gecko.gfx.RectUtils;
|
||||||
|
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
|
||||||
import org.mozilla.gecko.gfx.ViewportMetrics;
|
import org.mozilla.gecko.gfx.ViewportMetrics;
|
||||||
import org.mozilla.gecko.Tab.HistoryEntry;
|
import org.mozilla.gecko.Tab.HistoryEntry;
|
||||||
|
|
||||||
|
@ -216,8 +219,9 @@ abstract public class GeckoApp
|
||||||
public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>();
|
public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>();
|
||||||
|
|
||||||
String[] getPluginDirectories() {
|
String[] getPluginDirectories() {
|
||||||
// we don't support Honeycomb and later
|
// we don't support Honeycomb
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB &&
|
||||||
|
Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||||
return new String[0];
|
return new String[0];
|
||||||
|
|
||||||
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start of getPluginDirectories");
|
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start of getPluginDirectories");
|
||||||
|
@ -741,7 +745,7 @@ abstract public class GeckoApp
|
||||||
mLayerController.setWaitForTouchListeners(false);
|
mLayerController.setWaitForTouchListeners(false);
|
||||||
|
|
||||||
if (tab != null)
|
if (tab != null)
|
||||||
hidePluginViews(tab);
|
hidePlugins(tab, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1365,8 +1369,6 @@ abstract public class GeckoApp
|
||||||
mMainHandler.post(new Runnable() {
|
mMainHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
PluginLayoutParams lp;
|
PluginLayoutParams lp;
|
||||||
JSONObject viewportObject;
|
|
||||||
ViewportMetrics pluginViewport;
|
|
||||||
|
|
||||||
Tabs tabs = Tabs.getInstance();
|
Tabs tabs = Tabs.getInstance();
|
||||||
Tab tab = tabs.getSelectedTab();
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
@ -1375,9 +1377,10 @@ abstract public class GeckoApp
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ViewportMetrics targetViewport = mLayerController.getViewportMetrics();
|
ViewportMetrics targetViewport = mLayerController.getViewportMetrics();
|
||||||
|
ViewportMetrics pluginViewport;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
viewportObject = new JSONObject(metadata);
|
JSONObject viewportObject = new JSONObject(metadata);
|
||||||
pluginViewport = new ViewportMetrics(viewportObject);
|
pluginViewport = new ViewportMetrics(viewportObject);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e(LOGTAG, "Bad viewport metadata: ", e);
|
Log.e(LOGTAG, "Bad viewport metadata: ", e);
|
||||||
|
@ -1432,28 +1435,128 @@ abstract public class GeckoApp
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hidePluginViews() {
|
public Surface createSurface() {
|
||||||
|
Tabs tabs = Tabs.getInstance();
|
||||||
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
if (tab == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
SurfaceTextureLayer layer = SurfaceTextureLayer.create();
|
||||||
|
if (layer == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Surface surface = layer.getSurface();
|
||||||
|
tab.addPluginLayer(surface, layer);
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroySurface(Surface surface) {
|
||||||
|
Tabs tabs = Tabs.getInstance();
|
||||||
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
if (tab == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tab.removePluginLayer(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showSurface(Surface surface, int x, int y,
|
||||||
|
int w, int h, boolean inverted, boolean blend,
|
||||||
|
String metadata) {
|
||||||
|
Tabs tabs = Tabs.getInstance();
|
||||||
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
if (tab == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ViewportMetrics metrics;
|
||||||
|
try {
|
||||||
|
metrics = new ViewportMetrics(new JSONObject(metadata));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
Log.e(LOGTAG, "Bad viewport metadata: ", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PointF origin = metrics.getDisplayportOrigin();
|
||||||
|
x = x + (int)origin.x;
|
||||||
|
y = y + (int)origin.y;
|
||||||
|
|
||||||
|
LayerView layerView = mLayerController.getView();
|
||||||
|
SurfaceTextureLayer layer = (SurfaceTextureLayer)tab.getPluginLayer(surface);
|
||||||
|
if (layer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layer.update(new Point(x, y), new IntSize(w, h), metrics.getZoomFactor(), inverted, blend);
|
||||||
|
layerView.addLayer(layer);
|
||||||
|
|
||||||
|
// FIXME: shouldn't be necessary, layer will request
|
||||||
|
// one when it gets first frame
|
||||||
|
layerView.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hidePluginLayer(Layer layer) {
|
||||||
|
LayerView layerView = mLayerController.getView();
|
||||||
|
layerView.removeLayer(layer);
|
||||||
|
layerView.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showPluginLayer(Layer layer) {
|
||||||
|
LayerView layerView = mLayerController.getView();
|
||||||
|
layerView.addLayer(layer);
|
||||||
|
layerView.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideSurface(Surface surface) {
|
||||||
|
Tabs tabs = Tabs.getInstance();
|
||||||
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
if (tab == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Layer layer = tab.getPluginLayer(surface);
|
||||||
|
if (layer == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hidePluginLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void requestRender() {
|
||||||
|
mLayerController.getView().requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hidePlugins(boolean hideLayers) {
|
||||||
Tabs tabs = Tabs.getInstance();
|
Tabs tabs = Tabs.getInstance();
|
||||||
Tab tab = tabs.getSelectedTab();
|
Tab tab = tabs.getSelectedTab();
|
||||||
|
|
||||||
if (tab == null)
|
if (tab == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hidePluginViews(tab);
|
hidePlugins(tab, hideLayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hidePluginViews(Tab tab) {
|
public void hidePlugins(Tab tab, boolean hideLayers) {
|
||||||
for (View view : tab.getPluginViews()) {
|
for (View view : tab.getPluginViews()) {
|
||||||
view.setVisibility(View.GONE);
|
view.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hideLayers) {
|
||||||
|
for (Layer layer : tab.getPluginLayers()) {
|
||||||
|
hidePluginLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestRender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showPluginViews() {
|
public void showPlugins() {
|
||||||
repositionPluginViews(true);
|
repositionPluginViews(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showPluginViews(Tab tab) {
|
public void showPlugins(Tab tab) {
|
||||||
repositionPluginViews(tab, true);
|
repositionPluginViews(tab, true);
|
||||||
|
|
||||||
|
for (Layer layer : tab.getPluginLayers()) {
|
||||||
|
showPluginLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void repositionPluginViews(boolean setVisible) {
|
public void repositionPluginViews(boolean setVisible) {
|
||||||
|
@ -2610,8 +2713,10 @@ class PluginLayoutParams extends AbsoluteLayout.LayoutParams
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset(int aX, int aY, int aWidth, int aHeight, ViewportMetrics aViewport) {
|
public void reset(int aX, int aY, int aWidth, int aHeight, ViewportMetrics aViewport) {
|
||||||
x = mOriginalX = aX;
|
PointF origin = aViewport.getDisplayportOrigin();
|
||||||
y = mOriginalY = aY;
|
|
||||||
|
x = mOriginalX = aX + (int)origin.x;
|
||||||
|
y = mOriginalY = aY + (int)origin.y;
|
||||||
width = mOriginalWidth = aWidth;
|
width = mOriginalWidth = aWidth;
|
||||||
height = mOriginalHeight = aHeight;
|
height = mOriginalHeight = aHeight;
|
||||||
mOriginalViewport = aViewport;
|
mOriginalViewport = aViewport;
|
||||||
|
@ -2642,4 +2747,8 @@ class PluginLayoutParams extends AbsoluteLayout.LayoutParams
|
||||||
|
|
||||||
reposition(offset, viewport.getZoomFactor());
|
reposition(offset, viewport.getZoomFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float getLastResolution() {
|
||||||
|
return mLastResolution;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -226,6 +226,7 @@ public class GeckoAppShell
|
||||||
try {
|
try {
|
||||||
sHandler = lt.mHandlerQueue.take();
|
sHandler = lt.mHandlerQueue.take();
|
||||||
} catch (InterruptedException ie) {}
|
} catch (InterruptedException ie) {}
|
||||||
|
|
||||||
}
|
}
|
||||||
return sHandler;
|
return sHandler;
|
||||||
}
|
}
|
||||||
|
@ -567,7 +568,7 @@ public class GeckoAppShell
|
||||||
while (sGeckoPendingAcks.getCount() != 0) {
|
while (sGeckoPendingAcks.getCount() != 0) {
|
||||||
try {
|
try {
|
||||||
sGeckoPendingAcks.await();
|
sGeckoPendingAcks.await();
|
||||||
} catch (InterruptedException e) {}
|
} catch(InterruptedException e) {}
|
||||||
}
|
}
|
||||||
sGeckoPendingAcks = null;
|
sGeckoPendingAcks = null;
|
||||||
}
|
}
|
||||||
|
@ -1391,10 +1392,40 @@ public class GeckoAppShell
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void removePluginView(View view) {
|
public static void removePluginView(View view) {
|
||||||
Log.i(LOGTAG, "remove view:" + view);
|
Log.i(LOGTAG, "removePluginView:" + view);
|
||||||
GeckoApp.mAppContext.removePluginView(view);
|
GeckoApp.mAppContext.removePluginView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Surface createSurface() {
|
||||||
|
Log.i(LOGTAG, "createSurface");
|
||||||
|
return GeckoApp.mAppContext.createSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showSurface(Surface surface,
|
||||||
|
int x, int y,
|
||||||
|
int w, int h,
|
||||||
|
boolean inverted,
|
||||||
|
boolean blend,
|
||||||
|
String metadata)
|
||||||
|
{
|
||||||
|
Log.i(LOGTAG, "showSurface:" + surface + " @ x:" + x + " y:" + y + " w:" + w + " h:" + h + " inverted: " + inverted + " blend: " + blend + " metadata: " + metadata);
|
||||||
|
try {
|
||||||
|
GeckoApp.mAppContext.showSurface(surface, x, y, w, h, inverted, blend, metadata);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.i(LOGTAG, "Error in showSurface:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void hideSurface(Surface surface) {
|
||||||
|
Log.i(LOGTAG, "hideSurface:" + surface);
|
||||||
|
GeckoApp.mAppContext.hideSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void destroySurface(Surface surface) {
|
||||||
|
Log.i(LOGTAG, "destroySurface:" + surface);
|
||||||
|
GeckoApp.mAppContext.destroySurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<?> loadPluginClass(String className, String libName) {
|
public static Class<?> loadPluginClass(String className, String libName) {
|
||||||
Log.i(LOGTAG, "in loadPluginClass... attempting to access className, then libName.....");
|
Log.i(LOGTAG, "in loadPluginClass... attempting to access className, then libName.....");
|
||||||
Log.i(LOGTAG, "className: " + className);
|
Log.i(LOGTAG, "className: " + className);
|
||||||
|
|
|
@ -124,7 +124,9 @@ FENNEC_JAVA_FILES = \
|
||||||
gfx/RectUtils.java \
|
gfx/RectUtils.java \
|
||||||
gfx/ScrollbarLayer.java \
|
gfx/ScrollbarLayer.java \
|
||||||
gfx/SingleTileLayer.java \
|
gfx/SingleTileLayer.java \
|
||||||
|
gfx/SurfaceTextureLayer.java \
|
||||||
gfx/TextLayer.java \
|
gfx/TextLayer.java \
|
||||||
|
gfx/TextureGenerator.java \
|
||||||
gfx/TextureReaper.java \
|
gfx/TextureReaper.java \
|
||||||
gfx/TileLayer.java \
|
gfx/TileLayer.java \
|
||||||
gfx/ViewportMetrics.java \
|
gfx/ViewportMetrics.java \
|
||||||
|
|
|
@ -44,13 +44,16 @@ import android.graphics.drawable.Drawable;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.mozilla.gecko.db.BrowserDB;
|
import org.mozilla.gecko.db.BrowserDB;
|
||||||
|
import org.mozilla.gecko.gfx.Layer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -83,6 +86,7 @@ public final class Tab {
|
||||||
private String mContentType;
|
private String mContentType;
|
||||||
private boolean mHasTouchListeners;
|
private boolean mHasTouchListeners;
|
||||||
private ArrayList<View> mPluginViews;
|
private ArrayList<View> mPluginViews;
|
||||||
|
private HashMap<Surface, Layer> mPluginLayers;
|
||||||
|
|
||||||
public static final class HistoryEntry {
|
public static final class HistoryEntry {
|
||||||
public String mUri; // must never be null
|
public String mUri; // must never be null
|
||||||
|
@ -116,6 +120,7 @@ public final class Tab {
|
||||||
mDocumentURI = "";
|
mDocumentURI = "";
|
||||||
mContentType = "";
|
mContentType = "";
|
||||||
mPluginViews = new ArrayList<View>();
|
mPluginViews = new ArrayList<View>();
|
||||||
|
mPluginLayers = new HashMap<Surface, Layer>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
|
@ -558,4 +563,20 @@ public final class Tab {
|
||||||
public View[] getPluginViews() {
|
public View[] getPluginViews() {
|
||||||
return mPluginViews.toArray(new View[mPluginViews.size()]);
|
return mPluginViews.toArray(new View[mPluginViews.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addPluginLayer(Surface surface, Layer layer) {
|
||||||
|
mPluginLayers.put(surface, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Layer getPluginLayer(Surface surface) {
|
||||||
|
return mPluginLayers.get(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Layer> getPluginLayers() {
|
||||||
|
return mPluginLayers.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Layer removePluginLayer(Surface surface) {
|
||||||
|
return mPluginLayers.remove(surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ public class Tabs implements GeckoEventListener {
|
||||||
GeckoApp.mBrowserToolbar.setShadowVisibility(!(tab.getURL().startsWith("about:")));
|
GeckoApp.mBrowserToolbar.setShadowVisibility(!(tab.getURL().startsWith("about:")));
|
||||||
|
|
||||||
if (oldTab != null)
|
if (oldTab != null)
|
||||||
GeckoApp.mAppContext.hidePluginViews(oldTab);
|
GeckoApp.mAppContext.hidePlugins(oldTab, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -200,7 +200,7 @@ public class Tabs implements GeckoEventListener {
|
||||||
GeckoApp.mAppContext.onTabsChanged(closedTab);
|
GeckoApp.mAppContext.onTabsChanged(closedTab);
|
||||||
GeckoApp.mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
|
GeckoApp.mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
|
||||||
GeckoApp.mDoorHangerPopup.updatePopup();
|
GeckoApp.mDoorHangerPopup.updatePopup();
|
||||||
GeckoApp.mAppContext.hidePluginViews(closedTab);
|
GeckoApp.mAppContext.hidePlugins(closedTab, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,13 @@ import org.mozilla.gecko.FloatUtils;
|
||||||
public abstract class Layer {
|
public abstract class Layer {
|
||||||
private final ReentrantLock mTransactionLock;
|
private final ReentrantLock mTransactionLock;
|
||||||
private boolean mInTransaction;
|
private boolean mInTransaction;
|
||||||
private Point mOrigin;
|
|
||||||
private Point mNewOrigin;
|
private Point mNewOrigin;
|
||||||
private float mResolution;
|
|
||||||
private float mNewResolution;
|
private float mNewResolution;
|
||||||
private LayerView mView;
|
private LayerView mView;
|
||||||
|
|
||||||
|
protected Point mOrigin;
|
||||||
|
protected float mResolution;
|
||||||
|
|
||||||
public Layer() {
|
public Layer() {
|
||||||
mTransactionLock = new ReentrantLock();
|
mTransactionLock = new ReentrantLock();
|
||||||
mOrigin = new Point(0, 0);
|
mOrigin = new Point(0, 0);
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.mozilla.gecko.gfx.LayerView;
|
||||||
import org.mozilla.gecko.gfx.NinePatchTileLayer;
|
import org.mozilla.gecko.gfx.NinePatchTileLayer;
|
||||||
import org.mozilla.gecko.gfx.SingleTileLayer;
|
import org.mozilla.gecko.gfx.SingleTileLayer;
|
||||||
import org.mozilla.gecko.gfx.TextureReaper;
|
import org.mozilla.gecko.gfx.TextureReaper;
|
||||||
|
import org.mozilla.gecko.gfx.TextureGenerator;
|
||||||
import org.mozilla.gecko.gfx.TextLayer;
|
import org.mozilla.gecko.gfx.TextLayer;
|
||||||
import org.mozilla.gecko.gfx.TileLayer;
|
import org.mozilla.gecko.gfx.TileLayer;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -62,6 +63,7 @@ import android.view.WindowManager;
|
||||||
import javax.microedition.khronos.egl.EGLConfig;
|
import javax.microedition.khronos.egl.EGLConfig;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layer renderer implements the rendering logic for a layer view.
|
* The layer renderer implements the rendering logic for a layer view.
|
||||||
|
@ -90,6 +92,8 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||||
private RenderContext mLastPageContext;
|
private RenderContext mLastPageContext;
|
||||||
private int mMaxTextureSize;
|
private int mMaxTextureSize;
|
||||||
|
|
||||||
|
private ArrayList<Layer> mExtraLayers = new ArrayList<Layer>();
|
||||||
|
|
||||||
// Dropped frames display
|
// Dropped frames display
|
||||||
private int[] mFrameTimings;
|
private int[] mFrameTimings;
|
||||||
private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
|
private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
|
||||||
|
@ -152,12 +156,34 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||||
int maxTextureSizeResult[] = new int[1];
|
int maxTextureSizeResult[] = new int[1];
|
||||||
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
|
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
|
||||||
mMaxTextureSize = maxTextureSizeResult[0];
|
mMaxTextureSize = maxTextureSizeResult[0];
|
||||||
|
|
||||||
|
TextureGenerator.get().fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxTextureSize() {
|
public int getMaxTextureSize() {
|
||||||
return mMaxTextureSize;
|
return mMaxTextureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addLayer(Layer layer) {
|
||||||
|
LayerController controller = mView.getController();
|
||||||
|
|
||||||
|
synchronized (controller) {
|
||||||
|
if (mExtraLayers.contains(layer)) {
|
||||||
|
mExtraLayers.remove(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
mExtraLayers.add(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLayer(Layer layer) {
|
||||||
|
LayerController controller = mView.getController();
|
||||||
|
|
||||||
|
synchronized (controller) {
|
||||||
|
mExtraLayers.remove(layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called whenever a new frame is about to be drawn.
|
* Called whenever a new frame is about to be drawn.
|
||||||
*/
|
*/
|
||||||
|
@ -165,6 +191,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||||
long frameStartTime = SystemClock.uptimeMillis();
|
long frameStartTime = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
TextureReaper.get().reap(gl);
|
TextureReaper.get().reap(gl);
|
||||||
|
TextureGenerator.get().fill();
|
||||||
|
|
||||||
LayerController controller = mView.getController();
|
LayerController controller = mView.getController();
|
||||||
RenderContext screenContext = createScreenContext();
|
RenderContext screenContext = createScreenContext();
|
||||||
|
@ -198,6 +225,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||||
updated &= mVertScrollLayer.update(gl, pageContext);
|
updated &= mVertScrollLayer.update(gl, pageContext);
|
||||||
updated &= mHorizScrollLayer.update(gl, pageContext);
|
updated &= mHorizScrollLayer.update(gl, pageContext);
|
||||||
|
|
||||||
|
for (Layer layer : mExtraLayers)
|
||||||
|
updated &= layer.update(gl, pageContext);
|
||||||
|
|
||||||
/* Draw the background. */
|
/* Draw the background. */
|
||||||
mBackgroundLayer.draw(screenContext);
|
mBackgroundLayer.draw(screenContext);
|
||||||
|
|
||||||
|
@ -222,6 +252,10 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||||
|
|
||||||
gl.glDisable(GL10.GL_SCISSOR_TEST);
|
gl.glDisable(GL10.GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
/* Draw any extra layers that were added (likely plugins) */
|
||||||
|
for (Layer layer : mExtraLayers)
|
||||||
|
layer.draw(pageContext);
|
||||||
|
|
||||||
/* Draw the vertical scrollbar. */
|
/* Draw the vertical scrollbar. */
|
||||||
IntSize screenSize = new IntSize(controller.getViewportSize());
|
IntSize screenSize = new IntSize(controller.getViewportSize());
|
||||||
if (pageRect.height() > screenSize.height)
|
if (pageRect.height() > screenSize.height)
|
||||||
|
|
|
@ -224,6 +224,14 @@ public class LayerView extends GLSurfaceView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addLayer(Layer layer) {
|
||||||
|
mRenderer.addLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLayer(Layer layer) {
|
||||||
|
mRenderer.removeLayer(layer);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the time elapsed between the first call of requestRender() after
|
* Returns the time elapsed between the first call of requestRender() after
|
||||||
* the last call of getRenderTime(), in nanoseconds.
|
* the last call of getRenderTime(), in nanoseconds.
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Android code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
package org.mozilla.gecko.gfx;
|
||||||
|
|
||||||
|
import org.mozilla.gecko.GeckoApp;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.opengl.GLES11;
|
||||||
|
import android.opengl.GLES11Ext;
|
||||||
|
import android.opengl.Matrix;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Surface;
|
||||||
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
|
import javax.microedition.khronos.opengles.GL11Ext;
|
||||||
|
import java.nio.Buffer;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
import android.hardware.Camera;
|
||||||
|
|
||||||
|
public class SurfaceTextureLayer extends Layer implements SurfaceTexture.OnFrameAvailableListener {
|
||||||
|
private static final String LOGTAG = "SurfaceTextureLayer";
|
||||||
|
private static final int LOCAL_GL_TEXTURE_EXTERNAL_OES = 0x00008d65; // This is only defined in API level 15 for some reason (Android 4.0.3)
|
||||||
|
|
||||||
|
private final SurfaceTexture mSurfaceTexture;
|
||||||
|
private final Surface mSurface;
|
||||||
|
private int mTextureId;
|
||||||
|
private boolean mHaveFrame;
|
||||||
|
|
||||||
|
private IntSize mSize;
|
||||||
|
private IntSize mNewSize;
|
||||||
|
|
||||||
|
private boolean mInverted;
|
||||||
|
private boolean mNewInverted;
|
||||||
|
private boolean mBlend;
|
||||||
|
private boolean mNewBlend;
|
||||||
|
|
||||||
|
private FloatBuffer textureBuffer;
|
||||||
|
private FloatBuffer textureBufferInverted;
|
||||||
|
|
||||||
|
public SurfaceTextureLayer(int textureId) {
|
||||||
|
mTextureId = textureId;
|
||||||
|
mHaveFrame = true;
|
||||||
|
mInverted = false;
|
||||||
|
|
||||||
|
mSurfaceTexture = new SurfaceTexture(mTextureId);
|
||||||
|
mSurfaceTexture.setOnFrameAvailableListener(this);
|
||||||
|
|
||||||
|
mSurface = new Surface(mSurfaceTexture);
|
||||||
|
|
||||||
|
float textureMap[] = {
|
||||||
|
0.0f, 1.0f, // top left
|
||||||
|
0.0f, 0.0f, // bottom left
|
||||||
|
1.0f, 1.0f, // top right
|
||||||
|
1.0f, 0.0f, // bottom right
|
||||||
|
};
|
||||||
|
|
||||||
|
textureBuffer = createBuffer(textureMap);
|
||||||
|
|
||||||
|
float textureMapInverted[] = {
|
||||||
|
0.0f, 0.0f, // bottom left
|
||||||
|
0.0f, 1.0f, // top left
|
||||||
|
1.0f, 0.0f, // bottom right
|
||||||
|
1.0f, 1.0f, // top right
|
||||||
|
};
|
||||||
|
|
||||||
|
textureBufferInverted = createBuffer(textureMapInverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SurfaceTextureLayer create() {
|
||||||
|
int textureId = TextureGenerator.get().take();
|
||||||
|
if (textureId == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new SurfaceTextureLayer(textureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For SurfaceTexture.OnFrameAvailableListener
|
||||||
|
public void onFrameAvailable(SurfaceTexture texture) {
|
||||||
|
// FIXME: for some reason this doesn't get called
|
||||||
|
mHaveFrame = true;
|
||||||
|
GeckoApp.mAppContext.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
private FloatBuffer createBuffer(float[] input) {
|
||||||
|
// a float has 4 bytes so we allocate for each coordinate 4 bytes
|
||||||
|
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(input.length * 4);
|
||||||
|
byteBuffer.order(ByteOrder.nativeOrder());
|
||||||
|
|
||||||
|
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
|
||||||
|
floatBuffer.put(input);
|
||||||
|
floatBuffer.position(0);
|
||||||
|
|
||||||
|
return floatBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Point origin, IntSize size, float resolution, boolean inverted, boolean blend) {
|
||||||
|
beginTransaction(null);
|
||||||
|
|
||||||
|
setOrigin(origin);
|
||||||
|
setResolution(resolution);
|
||||||
|
|
||||||
|
mNewSize = size;
|
||||||
|
mNewInverted = inverted;
|
||||||
|
mNewBlend = blend;
|
||||||
|
|
||||||
|
endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IntSize getSize() { return mSize; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
if (mSurfaceTexture != null)
|
||||||
|
mSurfaceTexture.release();
|
||||||
|
|
||||||
|
if (mTextureId > 0)
|
||||||
|
TextureReaper.get().add(mTextureId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean performUpdates(GL10 gl, RenderContext context) {
|
||||||
|
super.performUpdates(gl, context);
|
||||||
|
|
||||||
|
if (mNewSize != null) {
|
||||||
|
mSize = mNewSize;
|
||||||
|
mNewSize = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
mInverted = mNewInverted;
|
||||||
|
mBlend = mNewBlend;
|
||||||
|
|
||||||
|
gl.glEnable(LOCAL_GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
gl.glBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mTextureId);
|
||||||
|
mSurfaceTexture.updateTexImage();
|
||||||
|
gl.glDisable(LOCAL_GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
|
||||||
|
// FIXME: we should return true and rely on onFrameAvailable, but
|
||||||
|
// that isn't working for some reason
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private float mapToGLCoords(float input, float viewport, boolean flip) {
|
||||||
|
if (flip) input = viewport - input;
|
||||||
|
return ((input / viewport) * 2.0f) - 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(RenderContext context) {
|
||||||
|
|
||||||
|
// Enable GL_TEXTURE_EXTERNAL_OES and bind our texture
|
||||||
|
GLES11.glEnable(LOCAL_GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
GLES11.glBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mTextureId);
|
||||||
|
|
||||||
|
// Enable vertex and texture coordinate buffers
|
||||||
|
GLES11.glEnableClientState(GL10.GL_VERTEX_ARRAY);
|
||||||
|
GLES11.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||||
|
|
||||||
|
// Load whatever texture transform the SurfaceMatrix needs
|
||||||
|
float[] matrix = new float[16];
|
||||||
|
mSurfaceTexture.getTransformMatrix(matrix);
|
||||||
|
GLES11.glMatrixMode(GLES11.GL_TEXTURE);
|
||||||
|
GLES11.glLoadMatrixf(matrix, 0);
|
||||||
|
|
||||||
|
// Figure out vertices to put the texture in the right spot on the screen
|
||||||
|
IntSize size = getSize();
|
||||||
|
RectF bounds = getBounds(context, new FloatSize(size));
|
||||||
|
RectF viewport = context.viewport;
|
||||||
|
bounds.offset(-viewport.left, -viewport.top);
|
||||||
|
|
||||||
|
float vertices[] = new float[8];
|
||||||
|
|
||||||
|
// Bottom left
|
||||||
|
vertices[0] = mapToGLCoords(bounds.left, viewport.width(), false);
|
||||||
|
vertices[1] = mapToGLCoords(bounds.bottom, viewport.height(), true);
|
||||||
|
|
||||||
|
// Top left
|
||||||
|
vertices[2] = mapToGLCoords(bounds.left, viewport.width(), false);
|
||||||
|
vertices[3] = mapToGLCoords(bounds.top, viewport.height(), true);
|
||||||
|
|
||||||
|
// Bottom right
|
||||||
|
vertices[4] = mapToGLCoords(bounds.right, viewport.width(), false);
|
||||||
|
vertices[5] = mapToGLCoords(bounds.bottom, viewport.height(), true);
|
||||||
|
|
||||||
|
// Top right
|
||||||
|
vertices[6] = mapToGLCoords(bounds.right, viewport.width(), false);
|
||||||
|
vertices[7] = mapToGLCoords(bounds.top, viewport.height(), true);
|
||||||
|
|
||||||
|
// Set texture and vertex buffers
|
||||||
|
GLES11.glVertexPointer(2, GL10.GL_FLOAT, 0, createBuffer(vertices));
|
||||||
|
GLES11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mInverted ? textureBufferInverted : textureBuffer);
|
||||||
|
|
||||||
|
if (mBlend) {
|
||||||
|
GLES11.glEnable(GL10.GL_BLEND);
|
||||||
|
GLES11.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the vertices as triangle strip
|
||||||
|
GLES11.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 2);
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
GLES11.glDisableClientState(GL10.GL_VERTEX_ARRAY);
|
||||||
|
GLES11.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
|
||||||
|
GLES11.glDisable(LOCAL_GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
GLES11.glLoadIdentity();
|
||||||
|
|
||||||
|
if (mBlend) {
|
||||||
|
GLES11.glDisable(GL10.GL_BLEND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SurfaceTexture getSurfaceTexture() {
|
||||||
|
return mSurfaceTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Surface getSurface() {
|
||||||
|
return mSurface;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Android code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
package org.mozilla.gecko.gfx;
|
||||||
|
|
||||||
|
import android.opengl.GLES10;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class TextureGenerator {
|
||||||
|
private static final int MIN_TEXTURES = 5;
|
||||||
|
|
||||||
|
private static TextureGenerator sSharedInstance;
|
||||||
|
private Stack<Integer> mTextureIds;
|
||||||
|
|
||||||
|
private TextureGenerator() { mTextureIds = new Stack<Integer>(); }
|
||||||
|
|
||||||
|
public static TextureGenerator get() {
|
||||||
|
if (sSharedInstance == null)
|
||||||
|
sSharedInstance = new TextureGenerator();
|
||||||
|
return sSharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized int take() {
|
||||||
|
if (mTextureIds.empty())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (int)mTextureIds.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void fill() {
|
||||||
|
int[] textures = new int[1];
|
||||||
|
while (mTextureIds.size() < MIN_TEXTURES) {
|
||||||
|
GLES10.glGenTextures(1, textures, 0);
|
||||||
|
mTextureIds.push(textures[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,11 @@ public class TextureReaper {
|
||||||
|
|
||||||
public void add(int[] textureIDs) {
|
public void add(int[] textureIDs) {
|
||||||
for (int textureID : textureIDs)
|
for (int textureID : textureIDs)
|
||||||
mDeadTextureIDs.add(textureID);
|
add(textureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int textureID) {
|
||||||
|
mDeadTextureIDs.add(textureID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reap(GL10 gl) {
|
public void reap(GL10 gl) {
|
||||||
|
|
|
@ -293,6 +293,7 @@ public class PanZoomController
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
cancelTouch();
|
cancelTouch();
|
||||||
|
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
|
||||||
// fall through
|
// fall through
|
||||||
case PANNING_HOLD_LOCKED:
|
case PANNING_HOLD_LOCKED:
|
||||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||||
|
@ -474,6 +475,8 @@ public class PanZoomController
|
||||||
stopAnimationTimer();
|
stopAnimationTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
|
||||||
|
|
||||||
mAnimationTimer = new Timer("Animation Timer");
|
mAnimationTimer = new Timer("Animation Timer");
|
||||||
mAnimationRunnable = runnable;
|
mAnimationRunnable = runnable;
|
||||||
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
|
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
@ -492,6 +495,8 @@ public class PanZoomController
|
||||||
mAnimationRunnable.terminate();
|
mAnimationRunnable.terminate();
|
||||||
mAnimationRunnable = null;
|
mAnimationRunnable = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeckoApp.mAppContext.showPlugins();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float getVelocity() {
|
private float getVelocity() {
|
||||||
|
@ -581,7 +586,6 @@ public class PanZoomController
|
||||||
finishBounce();
|
finishBounce();
|
||||||
finishAnimation();
|
finishAnimation();
|
||||||
mState = PanZoomState.NOTHING;
|
mState = PanZoomState.NOTHING;
|
||||||
GeckoApp.mAppContext.showPluginViews();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Performs one frame of a bounce animation. */
|
/* Performs one frame of a bounce animation. */
|
||||||
|
@ -661,6 +665,7 @@ public class PanZoomController
|
||||||
stopAnimationTimer();
|
stopAnimationTimer();
|
||||||
|
|
||||||
// Force a viewport synchronisation
|
// Force a viewport synchronisation
|
||||||
|
GeckoApp.mAppContext.showPlugins();
|
||||||
mController.setForceRedraw();
|
mController.setForceRedraw();
|
||||||
mController.notifyLayerClientOfGeometryChange();
|
mController.notifyLayerClientOfGeometryChange();
|
||||||
}
|
}
|
||||||
|
@ -741,7 +746,7 @@ public class PanZoomController
|
||||||
|
|
||||||
mState = PanZoomState.PINCHING;
|
mState = PanZoomState.PINCHING;
|
||||||
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
|
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||||
GeckoApp.mAppContext.hidePluginViews();
|
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers, only views */);
|
||||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||||
cancelTouch();
|
cancelTouch();
|
||||||
|
|
||||||
|
@ -806,9 +811,9 @@ public class PanZoomController
|
||||||
startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
|
startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
|
||||||
|
|
||||||
// Force a viewport synchronisation
|
// Force a viewport synchronisation
|
||||||
|
GeckoApp.mAppContext.showPlugins();
|
||||||
mController.setForceRedraw();
|
mController.setForceRedraw();
|
||||||
mController.notifyLayerClientOfGeometryChange();
|
mController.notifyLayerClientOfGeometryChange();
|
||||||
GeckoApp.mAppContext.showPluginViews();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getRedrawHint() {
|
public boolean getRedrawHint() {
|
||||||
|
@ -862,7 +867,6 @@ public class PanZoomController
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean animatedZoomTo(RectF zoomToRect) {
|
private boolean animatedZoomTo(RectF zoomToRect) {
|
||||||
GeckoApp.mAppContext.hidePluginViews();
|
|
||||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||||
|
|
||||||
mState = PanZoomState.ANIMATED_ZOOM;
|
mState = PanZoomState.ANIMATED_ZOOM;
|
||||||
|
|
|
@ -56,6 +56,7 @@ LOCAL_INCLUDES += \
|
||||||
-I$(topsrcdir)/dom/plugins/base/android \
|
-I$(topsrcdir)/dom/plugins/base/android \
|
||||||
-I$(topsrcdir)/gfx/skia/include/core \
|
-I$(topsrcdir)/gfx/skia/include/core \
|
||||||
-I$(topsrcdir)/gfx/skia/include/config \
|
-I$(topsrcdir)/gfx/skia/include/config \
|
||||||
|
-I$(topsrcdir)/gfx/gl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1709,9 +1709,9 @@ AndroidBridge::ReleaseNativeWindow(void *window)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AndroidBridge::SetNativeWindowFormat(void *window, int format)
|
AndroidBridge::SetNativeWindowFormat(void *window, int width, int height, int format)
|
||||||
{
|
{
|
||||||
return ANativeWindow_setBuffersGeometry(window, 0, 0, format) == 0;
|
return ANativeWindow_setBuffersGeometry(window, width, height, format) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1857,3 +1857,85 @@ extern "C" {
|
||||||
return jEnv;
|
return jEnv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject
|
||||||
|
AndroidBridge::CreateSurface()
|
||||||
|
{
|
||||||
|
#ifndef MOZ_JAVA_COMPOSITOR
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
AutoLocalJNIFrame frame(1);
|
||||||
|
|
||||||
|
JNIEnv* env = GetJNIForThread();
|
||||||
|
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||||
|
|
||||||
|
jmethodID method = env->GetStaticMethodID(cls,
|
||||||
|
"createSurface",
|
||||||
|
"()Landroid/view/Surface;");
|
||||||
|
|
||||||
|
jobject surface = env->CallStaticObjectMethod(cls, method);
|
||||||
|
if (surface)
|
||||||
|
env->NewGlobalRef(surface);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::DestroySurface(jobject surface)
|
||||||
|
{
|
||||||
|
#ifdef MOZ_JAVA_COMPOSITOR
|
||||||
|
AutoLocalJNIFrame frame(1);
|
||||||
|
|
||||||
|
JNIEnv* env = GetJNIForThread();
|
||||||
|
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||||
|
|
||||||
|
jmethodID method = env->GetStaticMethodID(cls,
|
||||||
|
"destroySurface",
|
||||||
|
"(Landroid/view/Surface;)V");
|
||||||
|
env->CallStaticVoidMethod(cls, method, surface);
|
||||||
|
env->DeleteGlobalRef(surface);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend)
|
||||||
|
{
|
||||||
|
#ifdef MOZ_JAVA_COMPOSITOR
|
||||||
|
AutoLocalJNIFrame frame;
|
||||||
|
|
||||||
|
JNIEnv* env = GetJNIForThread();
|
||||||
|
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||||
|
|
||||||
|
nsAutoString metadata;
|
||||||
|
nsCOMPtr<nsIAndroidDrawMetadataProvider> metadataProvider = GetDrawMetadataProvider();
|
||||||
|
metadataProvider->GetDrawMetadata(metadata);
|
||||||
|
|
||||||
|
jstring jMetadata = env->NewString(nsPromiseFlatString(metadata).get(), metadata.Length());
|
||||||
|
|
||||||
|
jmethodID method = env->GetStaticMethodID(cls,
|
||||||
|
"showSurface",
|
||||||
|
"(Landroid/view/Surface;IIIIZZLjava/lang/String;)V");
|
||||||
|
|
||||||
|
env->CallStaticVoidMethod(cls, method, surface,
|
||||||
|
(int)aRect.x, (int)aRect.y,
|
||||||
|
(int)aRect.width, (int)aRect.height,
|
||||||
|
aInverted, aBlend, jMetadata);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::HideSurface(jobject surface)
|
||||||
|
{
|
||||||
|
#ifdef MOZ_JAVA_COMPOSITOR
|
||||||
|
AutoLocalJNIFrame frame(1);
|
||||||
|
|
||||||
|
JNIEnv* env = GetJNIForThread();
|
||||||
|
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||||
|
|
||||||
|
jmethodID method = env->GetStaticMethodID(cls,
|
||||||
|
"hideSurface",
|
||||||
|
"(Landroid/view/Surface;)V");
|
||||||
|
env->CallStaticVoidMethod(cls, method, surface);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "nsIMutableArray.h"
|
#include "nsIMutableArray.h"
|
||||||
#include "nsIMIMEInfo.h"
|
#include "nsIMIMEInfo.h"
|
||||||
#include "nsColor.h"
|
#include "nsColor.h"
|
||||||
|
#include "gfxRect.h"
|
||||||
|
|
||||||
#include "nsIAndroidBridge.h"
|
#include "nsIAndroidBridge.h"
|
||||||
|
|
||||||
|
@ -341,7 +342,7 @@ public:
|
||||||
|
|
||||||
void *AcquireNativeWindow(jobject surface);
|
void *AcquireNativeWindow(jobject surface);
|
||||||
void ReleaseNativeWindow(void *window);
|
void ReleaseNativeWindow(void *window);
|
||||||
bool SetNativeWindowFormat(void *window, int format);
|
bool SetNativeWindowFormat(void *window, int width, int height, int format);
|
||||||
|
|
||||||
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
|
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
|
||||||
bool UnlockWindow(void *window);
|
bool UnlockWindow(void *window);
|
||||||
|
@ -378,6 +379,11 @@ public:
|
||||||
void EnableNetworkNotifications();
|
void EnableNetworkNotifications();
|
||||||
void DisableNetworkNotifications();
|
void DisableNetworkNotifications();
|
||||||
|
|
||||||
|
jobject CreateSurface();
|
||||||
|
void DestroySurface(jobject surface);
|
||||||
|
void ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend);
|
||||||
|
void HideSurface(jobject surface);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static AndroidBridge *sBridge;
|
static AndroidBridge *sBridge;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Corporation code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <android/log.h>
|
||||||
|
#include "AndroidMediaLayer.h"
|
||||||
|
#include "AndroidBridge.h"
|
||||||
|
|
||||||
|
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidMediaLayer" , ## args)
|
||||||
|
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
AndroidMediaLayer::AndroidMediaLayer()
|
||||||
|
: mInverted(false) {
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidMediaLayer::~AndroidMediaLayer() {
|
||||||
|
if (mContentData.window) {
|
||||||
|
AndroidBridge::Bridge()->ReleaseNativeWindow(mContentData.window);
|
||||||
|
mContentData.window = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mContentData.surface) {
|
||||||
|
AndroidBridge::Bridge()->DestroySurface(mContentData.surface);
|
||||||
|
mContentData.surface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<void*, SurfaceData*>::iterator it;
|
||||||
|
|
||||||
|
for (it = mVideoSurfaces.begin(); it != mVideoSurfaces.end(); it++) {
|
||||||
|
SurfaceData* data = it->second;
|
||||||
|
|
||||||
|
AndroidBridge::Bridge()->ReleaseNativeWindow(data->window);
|
||||||
|
AndroidBridge::Bridge()->DestroySurface(data->surface);
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVideoSurfaces.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AndroidMediaLayer::EnsureContentSurface() {
|
||||||
|
if (!mContentData.surface) {
|
||||||
|
mContentData.surface = AndroidBridge::Bridge()->CreateSurface();
|
||||||
|
if (mContentData.surface) {
|
||||||
|
mContentData.window = AndroidBridge::Bridge()->AcquireNativeWindow(mContentData.surface);
|
||||||
|
AndroidBridge::Bridge()->SetNativeWindowFormat(mContentData.window, 0, 0, AndroidBridge::WINDOW_FORMAT_RGBA_8888);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mContentData.surface && mContentData.window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* AndroidMediaLayer::GetNativeWindowForContent() {
|
||||||
|
if (!EnsureContentSurface())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return mContentData.window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* AndroidMediaLayer::RequestNativeWindowForVideo() {
|
||||||
|
jobject surface = AndroidBridge::Bridge()->CreateSurface();
|
||||||
|
if (surface) {
|
||||||
|
void* window = AndroidBridge::Bridge()->AcquireNativeWindow(surface);
|
||||||
|
if (window) {
|
||||||
|
AndroidBridge::Bridge()->SetNativeWindowFormat(window, 0, 0, AndroidBridge::WINDOW_FORMAT_RGBA_8888);
|
||||||
|
mVideoSurfaces[window] = new SurfaceData(surface, window);
|
||||||
|
return window;
|
||||||
|
} else {
|
||||||
|
LOG("Failed to create native window from surface");
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
AndroidBridge::Bridge()->DestroySurface(surface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidMediaLayer::ReleaseNativeWindowForVideo(void* aWindow) {
|
||||||
|
if (mVideoSurfaces.find(aWindow) == mVideoSurfaces.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SurfaceData* data = mVideoSurfaces[aWindow];
|
||||||
|
|
||||||
|
AndroidBridge::Bridge()->ReleaseNativeWindow(data->window);
|
||||||
|
AndroidBridge::Bridge()->DestroySurface(data->surface);
|
||||||
|
|
||||||
|
mVideoSurfaces.erase(aWindow);
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidMediaLayer::SetNativeWindowDimensions(void* aWindow, const gfxRect& aDimensions) {
|
||||||
|
if (mVideoSurfaces.find(aWindow) == mVideoSurfaces.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
SurfaceData* data = mVideoSurfaces[aWindow];
|
||||||
|
data->dimensions = aDimensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AndroidMediaLayer::UpdatePosition(const gfxRect& aRect, float aZoomLevel) {
|
||||||
|
|
||||||
|
std::map<void*, SurfaceData*>::iterator it;
|
||||||
|
|
||||||
|
if (EnsureContentSurface())
|
||||||
|
AndroidBridge::Bridge()->ShowSurface(mContentData.surface, aRect, mInverted, true);
|
||||||
|
|
||||||
|
for (it = mVideoSurfaces.begin(); it != mVideoSurfaces.end(); it++) {
|
||||||
|
SurfaceData* data = it->second;
|
||||||
|
|
||||||
|
// The video window dimension we get is not adjusted by zoom factor (unlike the
|
||||||
|
// content window). Fix it up here.
|
||||||
|
gfxRect scaledDimensions = data->dimensions;
|
||||||
|
scaledDimensions.Scale(aZoomLevel);
|
||||||
|
|
||||||
|
gfxRect videoRect(aRect.x + scaledDimensions.x, aRect.y + scaledDimensions.y,
|
||||||
|
scaledDimensions.width, scaledDimensions.height);
|
||||||
|
AndroidBridge::Bridge()->ShowSurface(data->surface, videoRect, mInverted, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* mozilla */
|
|
@ -0,0 +1,96 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||||
|
* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is Mozilla Corporation code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* James Willcox <jwillcox@mozilla.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef AndroidMediaLayer_h_
|
||||||
|
#define AndroidMediaLayer_h_
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <jni.h>
|
||||||
|
#include "gfxRect.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
|
class AndroidMediaLayer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
AndroidMediaLayer();
|
||||||
|
virtual ~AndroidMediaLayer();
|
||||||
|
|
||||||
|
void* GetNativeWindowForContent();
|
||||||
|
|
||||||
|
void* RequestNativeWindowForVideo();
|
||||||
|
void ReleaseNativeWindowForVideo(void* aWindow);
|
||||||
|
|
||||||
|
void SetNativeWindowDimensions(void* aWindow, const gfxRect& aDimensions);
|
||||||
|
|
||||||
|
void UpdatePosition(const gfxRect& aRect, float aZoomLevel);
|
||||||
|
|
||||||
|
bool Inverted() {
|
||||||
|
return mInverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetInverted(bool aInverted) {
|
||||||
|
mInverted = aInverted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool mInverted;
|
||||||
|
|
||||||
|
class SurfaceData {
|
||||||
|
public:
|
||||||
|
SurfaceData() :
|
||||||
|
surface(NULL), window(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SurfaceData(jobject aSurface, void* aWindow) :
|
||||||
|
surface(aSurface), window(aWindow) {
|
||||||
|
}
|
||||||
|
|
||||||
|
jobject surface;
|
||||||
|
void* window;
|
||||||
|
gfxRect dimensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool EnsureContentSurface();
|
||||||
|
|
||||||
|
SurfaceData mContentData;
|
||||||
|
std::map<void*, SurfaceData*> mVideoSurfaces;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* mozilla */
|
||||||
|
#endif /* AndroidMediaLayer_h_ */
|
|
@ -68,6 +68,7 @@ CPPSRCS = \
|
||||||
AndroidDirectTexture.cpp \
|
AndroidDirectTexture.cpp \
|
||||||
AndroidGraphicBuffer.cpp \
|
AndroidGraphicBuffer.cpp \
|
||||||
AndroidJNI.cpp \
|
AndroidJNI.cpp \
|
||||||
|
AndroidMediaLayer.cpp \
|
||||||
nsWindow.cpp \
|
nsWindow.cpp \
|
||||||
nsLookAndFeel.cpp \
|
nsLookAndFeel.cpp \
|
||||||
nsScreenManagerAndroid.cpp \
|
nsScreenManagerAndroid.cpp \
|
||||||
|
|
|
@ -1019,7 +1019,7 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
||||||
if (surface) {
|
if (surface) {
|
||||||
sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(surface);
|
sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(surface);
|
||||||
if (sNativeWindow) {
|
if (sNativeWindow) {
|
||||||
AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, AndroidBridge::WINDOW_FORMAT_RGB_565);
|
AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, 0, 0, AndroidBridge::WINDOW_FORMAT_RGB_565);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче