mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 721741 - Add support for Flash on Android 4.0+ r=blassey
This commit is contained in:
parent
6982c1b717
commit
de86b5b89d
@ -138,6 +138,7 @@ endif
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-DSK_BUILD_FOR_ANDROID_NDK \
|
||||
-I$(topsrcdir)/widget/android \
|
||||
-I$(topsrcdir)/xpcom/base/ \
|
||||
-I$(topsrcdir)/gfx/skia/include/core \
|
||||
-I$(topsrcdir)/gfx/skia/include/config \
|
||||
|
@ -306,7 +306,6 @@ anp_audio_start(ANPAudioTrack* s)
|
||||
|
||||
if (s->keepGoing) {
|
||||
// we are already playing. Ignore.
|
||||
LOG("anp_audio_start called twice!");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -359,7 +358,14 @@ anp_audio_isStopped(ANPAudioTrack* s)
|
||||
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));
|
||||
ASSIGN(i, newTrack);
|
||||
ASSIGN(i, deleteTrack);
|
||||
@ -368,3 +374,14 @@ void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i) {
|
||||
ASSIGN(i, stop);
|
||||
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 ***** */
|
||||
|
||||
#include "android_npapi.h"
|
||||
#include <stdlib.h>
|
||||
#include "android_npapi.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
@ -53,7 +53,8 @@
|
||||
"!!!!!!!!!!!!!! %s not implemented %s, %d", \
|
||||
__PRETTY_FUNCTION__, __FILE__, __LINE__); \
|
||||
|
||||
void InitAudioTrackInterface(ANPAudioTrackInterfaceV0 *i);
|
||||
void InitAudioTrackInterfaceV0(ANPAudioTrackInterfaceV0 *i);
|
||||
void InitAudioTrackInterfaceV1(ANPAudioTrackInterfaceV1* i);
|
||||
void InitBitmapInterface(ANPBitmapInterfaceV0 *i);
|
||||
void InitCanvasInterface(ANPCanvasInterfaceV0 *i);
|
||||
void InitEventInterface(ANPEventInterfaceV0 *i);
|
||||
@ -63,5 +64,13 @@ void InitPaintInterface(ANPPaintInterfaceV0 *i);
|
||||
void InitPathInterface(ANPPathInterfaceV0 *i);
|
||||
void InitSurfaceInterface(ANPSurfaceInterfaceV0 *i);
|
||||
void InitSystemInterface(ANPSystemInterfaceV0 *i);
|
||||
void InitSystemInterfaceV1(ANPSystemInterfaceV1 *i);
|
||||
void InitSystemInterfaceV2(ANPSystemInterfaceV2 *i);
|
||||
void InitTypeFaceInterface(ANPTypefaceInterfaceV0 *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);
|
||||
|
85
dom/plugins/base/android/ANPNativeWindow.cpp
Normal file
85
dom/plugins/base/android/ANPNativeWindow.cpp
Normal file
@ -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);
|
||||
}
|
65
dom/plugins/base/android/ANPOpenGL.cpp
Normal file
65
dom/plugins/base/android/ANPOpenGL.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
const char*
|
||||
anp_system_getApplicationDataDirectory(NPP instance)
|
||||
{
|
||||
return anp_system_getApplicationDataDirectory();
|
||||
}
|
||||
|
||||
jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
||||
{
|
||||
LOG("%s", __PRETTY_FUNCTION__);
|
||||
@ -88,8 +94,27 @@ jclass anp_system_loadJavaClass(NPP instance, const char* className)
|
||||
return reinterpret_cast<jclass>(obj);
|
||||
}
|
||||
|
||||
void anp_system_setPowerState(NPP instance, ANPPowerState powerState)
|
||||
{
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
void InitSystemInterface(ANPSystemInterfaceV0 *i) {
|
||||
_assert(i->inSize == sizeof(*i));
|
||||
ASSIGN(i, getApplicationDataDirectory);
|
||||
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);
|
||||
}
|
||||
|
109
dom/plugins/base/android/ANPVideo.cpp
Normal file
109
dom/plugins/base/android/ANPVideo.cpp
Normal file
@ -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 "ANPBase.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 ASSIGN(obj, name) (obj)->name = anp_window_##name
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
anp_window_setVisibleRects(NPP instance, const ANPRectI rects[], int32_t count)
|
||||
{
|
||||
@ -79,6 +85,32 @@ anp_window_requestCenterFitZoom(NPP instance)
|
||||
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) {
|
||||
_assert(i->inSize == sizeof(*i));
|
||||
ASSIGN(i, setVisibleRects);
|
||||
@ -89,3 +121,26 @@ void InitWindowInterface(ANPWindowInterfaceV0 *i) {
|
||||
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 \
|
||||
ANPBitmap.cpp \
|
||||
ANPLog.cpp \
|
||||
ANPNativeWindow.cpp \
|
||||
ANPSurface.cpp \
|
||||
ANPVideo.cpp \
|
||||
ANPOpenGL.cpp \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/widget/android \
|
||||
-I$(topsrcdir)/dom/plugins/base \
|
||||
-I$(topsrcdir)/dom/plugins/base/android/include \
|
||||
-I$(topsrcdir)/gfx/gl \
|
||||
$(MOZ_CAIRO_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
|
@ -36,8 +36,9 @@
|
||||
#define android_npapi_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "npapi.h"
|
||||
#include <jni.h>
|
||||
#include "npapi.h"
|
||||
#include "GLDefs.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// General types
|
||||
@ -120,6 +121,16 @@ typedef uint32_t ANPMatrixFlag;
|
||||
#define kSystemInterfaceV0_ANPGetValue ((NPNVariable)1010)
|
||||
#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.
|
||||
|
||||
NPN_GetValue(inst, kSupportedDrawingModel_ANPGetValue, uint32_t* bits)
|
||||
@ -180,6 +191,7 @@ enum ANPDrawingModels {
|
||||
surface object.
|
||||
*/
|
||||
kSurface_ANPDrawingModel = 1 << 1,
|
||||
kOpenGL_ANPDrawingModel = 1 << 2,
|
||||
};
|
||||
typedef int32_t ANPDrawingModel;
|
||||
|
||||
@ -678,6 +690,25 @@ struct ANPWindowInterfaceV0 : ANPInterface {
|
||||
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 {
|
||||
@ -762,6 +793,12 @@ struct ANPAudioTrackInterfaceV0 : ANPInterface {
|
||||
bool (*isStopped)(ANPAudioTrack*);
|
||||
};
|
||||
|
||||
struct ANPAudioTrackInterfaceV1 : ANPAudioTrackInterfaceV0 {
|
||||
/** Returns the track's latency in milliseconds. */
|
||||
uint32_t (*trackLatency)(ANPAudioTrack*);
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// DEFINITION OF VALUES PASSED THROUGH NPP_HandleEvent
|
||||
|
||||
@ -922,12 +959,16 @@ struct ANPEvent {
|
||||
// use based on the value in model
|
||||
union {
|
||||
ANPBitmap bitmap;
|
||||
struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
} surfaceSize;
|
||||
} data;
|
||||
} draw;
|
||||
int32_t other[8];
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
struct ANPEventInterfaceV0 : ANPInterface {
|
||||
/** 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
|
||||
@ -976,4 +1017,117 @@ typedef uint32_t uint32;
|
||||
typedef int16_t int16;
|
||||
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
|
||||
|
@ -132,9 +132,10 @@ using mozilla::plugins::PluginModuleParent;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include <android/log.h>
|
||||
#include "android_npapi.h"
|
||||
#include "ANPBase.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include <android/log.h>
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||
#endif
|
||||
|
||||
@ -2348,7 +2349,7 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
case kAudioTrackInterfaceV0_ANPGetValue: {
|
||||
LOG("get audio interface");
|
||||
ANPAudioTrackInterfaceV0 *i = (ANPAudioTrackInterfaceV0 *) result;
|
||||
InitAudioTrackInterface(i);
|
||||
InitAudioTrackInterfaceV0(i);
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -2363,7 +2364,6 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
LOG("get system interface");
|
||||
ANPSystemInterfaceV0* i = reinterpret_cast<ANPSystemInterfaceV0*>(result);
|
||||
InitSystemInterface(i);
|
||||
LOG("done system interface");
|
||||
return NPERR_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -2395,6 +2395,71 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
*i = reinterpret_cast<int32_t>(ret);
|
||||
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
|
||||
|
||||
// we no longer hand out any XPCOM objects
|
||||
|
@ -152,6 +152,8 @@ public:
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
PRUint32 GetANPDrawingModel() { return mANPDrawingModel; }
|
||||
void SetANPDrawingModel(PRUint32 aModel);
|
||||
|
||||
// This stuff is for kSurface_ANPDrawingModel
|
||||
void* GetJavaSurface();
|
||||
void SetJavaSurface(void* aSurface);
|
||||
void RequestJavaSurface();
|
||||
|
@ -120,6 +120,7 @@ static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
|
||||
#include "ANPBase.h"
|
||||
#include "android_npapi.h"
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidMediaLayer.h"
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#include <android/log.h>
|
||||
@ -323,8 +324,9 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||
mWaitingForPaint = false;
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
mPluginViewAdded = false;
|
||||
mLastPluginRect = gfxRect(0, 0, 0, 0);
|
||||
mOnScreen = false;
|
||||
mInverted = false;
|
||||
mLayer = new AndroidMediaLayer();
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -380,6 +382,13 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
||||
mPluginWindow = nsnull;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (mLayer) {
|
||||
delete mLayer;
|
||||
mLayer = nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mInstance) {
|
||||
mInstance->InvalidateOwner();
|
||||
}
|
||||
@ -1658,6 +1667,43 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY)
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
void* javaSurface = mInstance->GetJavaSurface();
|
||||
@ -1666,11 +1712,6 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aRect.IsEqualEdges(mLastPluginRect)) {
|
||||
// Already added and in position, no work to do
|
||||
return true;
|
||||
}
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
if (!env)
|
||||
return false;
|
||||
@ -1713,26 +1754,16 @@ bool nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||
aRect.height);
|
||||
#endif
|
||||
|
||||
if (!mPluginViewAdded) {
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kLifecycle_ANPEventType;
|
||||
event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
|
||||
mInstance->HandleEvent(&event, nsnull);
|
||||
|
||||
mPluginViewAdded = true;
|
||||
}
|
||||
SendOnScreenEvent(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::RemovePluginView()
|
||||
{
|
||||
if (!mInstance || !mObjectFrame | !mPluginViewAdded)
|
||||
if (!mInstance || !mObjectFrame | !mOnScreen)
|
||||
return;
|
||||
|
||||
mPluginViewAdded = false;
|
||||
|
||||
void* surface = mInstance->GetJavaSurface();
|
||||
if (!surface)
|
||||
return;
|
||||
@ -1748,13 +1779,17 @@ void nsPluginInstanceOwner::RemovePluginView()
|
||||
"removePluginView",
|
||||
"(Landroid/view/View;)V");
|
||||
env->CallStaticVoidMethod(cls, method, surface);
|
||||
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kLifecycle_ANPEventType;
|
||||
event.data.lifecycle.action = kOffScreen_ANPLifecycleAction;
|
||||
mInstance->HandleEvent(&event, nsnull);
|
||||
SendOnScreenEvent(false);
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::Invalidate() {
|
||||
NPRect rect;
|
||||
rect.left = rect.top = 0;
|
||||
rect.right = mPluginWindow->width;
|
||||
rect.bottom = mPluginWindow->height;
|
||||
InvalidateRect(&rect);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
||||
@ -2779,7 +2814,15 @@ nsPluginInstanceOwner::PrepareToStop(bool aDelayedStop)
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
// Unregister scroll position listeners
|
||||
@ -2891,15 +2934,21 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||
|
||||
if (model == kSurface_ANPDrawingModel) {
|
||||
if (!AddPluginView(aFrameRect)) {
|
||||
NPRect rect;
|
||||
rect.left = rect.top = 0;
|
||||
rect.right = aFrameRect.width;
|
||||
rect.bottom = aFrameRect.height;
|
||||
InvalidateRect(&rect);
|
||||
Invalidate();
|
||||
}
|
||||
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)
|
||||
return;
|
||||
|
||||
@ -3590,8 +3639,16 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(bool aSetWindow)
|
||||
} else {
|
||||
mPluginWindow->clipRect.right = 0;
|
||||
mPluginWindow->clipRect.bottom = 0;
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
RemovePluginView();
|
||||
#if 0 //MOZ_WIDGET_ANDROID
|
||||
if (mInstance) {
|
||||
PRInt32 model = mInstance->GetANPDrawingModel();
|
||||
|
||||
if (model == kSurface_ANPDrawingModel) {
|
||||
RemovePluginView();
|
||||
} else if (model == kOpenGL_ANPDrawingModel) {
|
||||
HidePluginLayer();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,12 @@ class gfxXlibSurface;
|
||||
#include <os2.h>
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
namespace mozilla {
|
||||
class AndroidMediaLayer;
|
||||
}
|
||||
#endif
|
||||
|
||||
// X.h defines KeyPress
|
||||
#ifdef KeyPress
|
||||
#undef KeyPress
|
||||
@ -297,6 +303,26 @@ public:
|
||||
void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect);
|
||||
|
||||
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:
|
||||
|
||||
@ -310,10 +336,17 @@ private:
|
||||
|
||||
void FixUpURLS(const nsString &name, nsAString &value);
|
||||
#ifdef ANDROID
|
||||
void SendSize(int width, int height);
|
||||
void SendOnScreenEvent(bool onScreen);
|
||||
|
||||
bool AddPluginView(const gfxRect& aRect);
|
||||
void RemovePluginView();
|
||||
bool mPluginViewAdded;
|
||||
gfxRect mLastPluginRect;
|
||||
|
||||
bool mOnScreen;
|
||||
bool mInverted;
|
||||
|
||||
// For kOpenGL_ANPDrawingModel
|
||||
mozilla::AndroidMediaLayer *mLayer;
|
||||
#endif
|
||||
|
||||
nsPluginNativeWindow *mPluginWindow;
|
||||
|
@ -1695,7 +1695,6 @@ nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
|
||||
// The matrix includes the frame's position, so we need to transform
|
||||
// from 0,0 to get the correct coordinates.
|
||||
frameGfxRect.MoveTo(0, 0);
|
||||
matrix2d.NudgeToIntegers();
|
||||
|
||||
mInstanceOwner->Paint(ctx, matrix2d.Transform(frameGfxRect), dirtyGfxRect);
|
||||
return;
|
||||
|
@ -44,10 +44,12 @@ import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.gfx.FloatSize;
|
||||
import org.mozilla.gecko.gfx.GeckoSoftwareLayerClient;
|
||||
import org.mozilla.gecko.gfx.IntSize;
|
||||
import org.mozilla.gecko.gfx.Layer;
|
||||
import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PlaceholderLayerClient;
|
||||
import org.mozilla.gecko.gfx.RectUtils;
|
||||
import org.mozilla.gecko.gfx.SurfaceTextureLayer;
|
||||
import org.mozilla.gecko.gfx.ViewportMetrics;
|
||||
import org.mozilla.gecko.Tab.HistoryEntry;
|
||||
|
||||
@ -217,8 +219,9 @@ abstract public class GeckoApp
|
||||
public ArrayList<PackageInfo> mPackageInfoCache = new ArrayList<PackageInfo>();
|
||||
|
||||
String[] getPluginDirectories() {
|
||||
// we don't support Honeycomb and later
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
// we don't support Honeycomb
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB &&
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
return new String[0];
|
||||
|
||||
Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start of getPluginDirectories");
|
||||
@ -749,7 +752,7 @@ abstract public class GeckoApp
|
||||
mLayerController.setWaitForTouchListeners(false);
|
||||
|
||||
if (tab != null)
|
||||
hidePluginViews(tab);
|
||||
hidePlugins(tab, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1374,8 +1377,6 @@ abstract public class GeckoApp
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
PluginLayoutParams lp;
|
||||
JSONObject viewportObject;
|
||||
ViewportMetrics pluginViewport;
|
||||
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
@ -1384,9 +1385,10 @@ abstract public class GeckoApp
|
||||
return;
|
||||
|
||||
ViewportMetrics targetViewport = mLayerController.getViewportMetrics();
|
||||
ViewportMetrics pluginViewport;
|
||||
|
||||
try {
|
||||
viewportObject = new JSONObject(metadata);
|
||||
JSONObject viewportObject = new JSONObject(metadata);
|
||||
pluginViewport = new ViewportMetrics(viewportObject);
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Bad viewport metadata: ", e);
|
||||
@ -1441,28 +1443,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();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
hidePluginViews(tab);
|
||||
hidePlugins(tab, hideLayers);
|
||||
}
|
||||
|
||||
public void hidePluginViews(Tab tab) {
|
||||
public void hidePlugins(Tab tab, boolean hideLayers) {
|
||||
for (View view : tab.getPluginViews()) {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (hideLayers) {
|
||||
for (Layer layer : tab.getPluginLayers()) {
|
||||
hidePluginLayer(layer);
|
||||
}
|
||||
|
||||
requestRender();
|
||||
}
|
||||
}
|
||||
|
||||
public void showPluginViews() {
|
||||
public void showPlugins() {
|
||||
repositionPluginViews(true);
|
||||
}
|
||||
|
||||
public void showPluginViews(Tab tab) {
|
||||
public void showPlugins(Tab tab) {
|
||||
repositionPluginViews(tab, true);
|
||||
|
||||
for (Layer layer : tab.getPluginLayers()) {
|
||||
showPluginLayer(layer);
|
||||
}
|
||||
|
||||
requestRender();
|
||||
}
|
||||
|
||||
public void repositionPluginViews(boolean setVisible) {
|
||||
@ -2619,8 +2721,10 @@ class PluginLayoutParams extends AbsoluteLayout.LayoutParams
|
||||
}
|
||||
|
||||
public void reset(int aX, int aY, int aWidth, int aHeight, ViewportMetrics aViewport) {
|
||||
x = mOriginalX = aX;
|
||||
y = mOriginalY = aY;
|
||||
PointF origin = aViewport.getDisplayportOrigin();
|
||||
|
||||
x = mOriginalX = aX + (int)origin.x;
|
||||
y = mOriginalY = aY + (int)origin.y;
|
||||
width = mOriginalWidth = aWidth;
|
||||
height = mOriginalHeight = aHeight;
|
||||
mOriginalViewport = aViewport;
|
||||
@ -2651,4 +2755,8 @@ class PluginLayoutParams extends AbsoluteLayout.LayoutParams
|
||||
|
||||
reposition(offset, viewport.getZoomFactor());
|
||||
}
|
||||
|
||||
public float getLastResolution() {
|
||||
return mLastResolution;
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,7 @@ public class GeckoAppShell
|
||||
try {
|
||||
sHandler = lt.mHandlerQueue.take();
|
||||
} catch (InterruptedException ie) {}
|
||||
|
||||
}
|
||||
return sHandler;
|
||||
}
|
||||
@ -567,7 +568,7 @@ public class GeckoAppShell
|
||||
while (sGeckoPendingAcks.getCount() != 0) {
|
||||
try {
|
||||
sGeckoPendingAcks.await();
|
||||
} catch (InterruptedException e) {}
|
||||
} catch(InterruptedException e) {}
|
||||
}
|
||||
sGeckoPendingAcks = null;
|
||||
}
|
||||
@ -1391,10 +1392,40 @@ public class GeckoAppShell
|
||||
}
|
||||
|
||||
public static void removePluginView(View view) {
|
||||
Log.i(LOGTAG, "remove view:" + view);
|
||||
Log.i(LOGTAG, "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) {
|
||||
Log.i(LOGTAG, "in loadPluginClass... attempting to access className, then libName.....");
|
||||
Log.i(LOGTAG, "className: " + className);
|
||||
|
@ -124,7 +124,9 @@ FENNEC_JAVA_FILES = \
|
||||
gfx/RectUtils.java \
|
||||
gfx/ScrollbarLayer.java \
|
||||
gfx/SingleTileLayer.java \
|
||||
gfx/SurfaceTextureLayer.java \
|
||||
gfx/TextLayer.java \
|
||||
gfx/TextureGenerator.java \
|
||||
gfx/TextureReaper.java \
|
||||
gfx/TileLayer.java \
|
||||
gfx/ViewportMetrics.java \
|
||||
|
@ -44,13 +44,16 @@ import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.gfx.Layer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@ -83,6 +86,7 @@ public final class Tab {
|
||||
private String mContentType;
|
||||
private boolean mHasTouchListeners;
|
||||
private ArrayList<View> mPluginViews;
|
||||
private HashMap<Surface, Layer> mPluginLayers;
|
||||
private boolean mHasLoaded;
|
||||
|
||||
public static final class HistoryEntry {
|
||||
@ -117,6 +121,7 @@ public final class Tab {
|
||||
mDocumentURI = "";
|
||||
mContentType = "";
|
||||
mPluginViews = new ArrayList<View>();
|
||||
mPluginLayers = new HashMap<Surface, Layer>();
|
||||
mHasLoaded = false;
|
||||
}
|
||||
|
||||
@ -568,4 +573,20 @@ public final class Tab {
|
||||
public View[] getPluginViews() {
|
||||
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:")));
|
||||
|
||||
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.mBrowserToolbar.updateTabs(Tabs.getInstance().getCount());
|
||||
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 {
|
||||
private final ReentrantLock mTransactionLock;
|
||||
private boolean mInTransaction;
|
||||
private Point mOrigin;
|
||||
private Point mNewOrigin;
|
||||
private float mResolution;
|
||||
private float mNewResolution;
|
||||
private LayerView mView;
|
||||
|
||||
protected Point mOrigin;
|
||||
protected float mResolution;
|
||||
|
||||
public Layer() {
|
||||
mTransactionLock = new ReentrantLock();
|
||||
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.SingleTileLayer;
|
||||
import org.mozilla.gecko.gfx.TextureReaper;
|
||||
import org.mozilla.gecko.gfx.TextureGenerator;
|
||||
import org.mozilla.gecko.gfx.TextLayer;
|
||||
import org.mozilla.gecko.gfx.TileLayer;
|
||||
import android.content.Context;
|
||||
@ -62,6 +63,7 @@ import android.view.WindowManager;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 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 int mMaxTextureSize;
|
||||
|
||||
private ArrayList<Layer> mExtraLayers = new ArrayList<Layer>();
|
||||
|
||||
// Dropped frames display
|
||||
private int[] mFrameTimings;
|
||||
private int mCurrentFrame, mFrameTimingsSum, mDroppedFrames;
|
||||
@ -152,12 +156,34 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
int maxTextureSizeResult[] = new int[1];
|
||||
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSizeResult, 0);
|
||||
mMaxTextureSize = maxTextureSizeResult[0];
|
||||
|
||||
TextureGenerator.get().fill();
|
||||
}
|
||||
|
||||
public int getMaxTextureSize() {
|
||||
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.
|
||||
*/
|
||||
@ -165,6 +191,7 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
long frameStartTime = SystemClock.uptimeMillis();
|
||||
|
||||
TextureReaper.get().reap(gl);
|
||||
TextureGenerator.get().fill();
|
||||
|
||||
LayerController controller = mView.getController();
|
||||
RenderContext screenContext = createScreenContext();
|
||||
@ -198,6 +225,9 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
updated &= mVertScrollLayer.update(gl, pageContext);
|
||||
updated &= mHorizScrollLayer.update(gl, pageContext);
|
||||
|
||||
for (Layer layer : mExtraLayers)
|
||||
updated &= layer.update(gl, pageContext);
|
||||
|
||||
/* Draw the background. */
|
||||
mBackgroundLayer.draw(screenContext);
|
||||
|
||||
@ -222,6 +252,10 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
||||
|
||||
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. */
|
||||
IntSize screenSize = new IntSize(controller.getViewportSize());
|
||||
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
|
||||
* the last call of getRenderTime(), in nanoseconds.
|
||||
|
259
mobile/android/base/gfx/SurfaceTextureLayer.java
Normal file
259
mobile/android/base/gfx/SurfaceTextureLayer.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
73
mobile/android/base/gfx/TextureGenerator.java
Normal file
73
mobile/android/base/gfx/TextureGenerator.java
Normal file
@ -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) {
|
||||
for (int textureID : textureIDs)
|
||||
mDeadTextureIDs.add(textureID);
|
||||
add(textureID);
|
||||
}
|
||||
|
||||
public void add(int textureID) {
|
||||
mDeadTextureIDs.add(textureID);
|
||||
}
|
||||
|
||||
public void reap(GL10 gl) {
|
||||
|
@ -293,6 +293,7 @@ public class PanZoomController
|
||||
return false;
|
||||
}
|
||||
cancelTouch();
|
||||
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
|
||||
// fall through
|
||||
case PANNING_HOLD_LOCKED:
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
@ -474,6 +475,8 @@ public class PanZoomController
|
||||
stopAnimationTimer();
|
||||
}
|
||||
|
||||
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers */);
|
||||
|
||||
mAnimationTimer = new Timer("Animation Timer");
|
||||
mAnimationRunnable = runnable;
|
||||
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@ -492,6 +495,8 @@ public class PanZoomController
|
||||
mAnimationRunnable.terminate();
|
||||
mAnimationRunnable = null;
|
||||
}
|
||||
|
||||
GeckoApp.mAppContext.showPlugins();
|
||||
}
|
||||
|
||||
private float getVelocity() {
|
||||
@ -581,7 +586,6 @@ public class PanZoomController
|
||||
finishBounce();
|
||||
finishAnimation();
|
||||
mState = PanZoomState.NOTHING;
|
||||
GeckoApp.mAppContext.showPluginViews();
|
||||
}
|
||||
|
||||
/* Performs one frame of a bounce animation. */
|
||||
@ -661,6 +665,7 @@ public class PanZoomController
|
||||
stopAnimationTimer();
|
||||
|
||||
// Force a viewport synchronisation
|
||||
GeckoApp.mAppContext.showPlugins();
|
||||
mController.setForceRedraw();
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
}
|
||||
@ -741,7 +746,7 @@ public class PanZoomController
|
||||
|
||||
mState = PanZoomState.PINCHING;
|
||||
mLastZoomFocus = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||
GeckoApp.mAppContext.hidePluginViews();
|
||||
GeckoApp.mAppContext.hidePlugins(false /* don't hide layers, only views */);
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
cancelTouch();
|
||||
|
||||
@ -806,9 +811,9 @@ public class PanZoomController
|
||||
startTouch(detector.getFocusX(), detector.getFocusY(), detector.getEventTime());
|
||||
|
||||
// Force a viewport synchronisation
|
||||
GeckoApp.mAppContext.showPlugins();
|
||||
mController.setForceRedraw();
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
GeckoApp.mAppContext.showPluginViews();
|
||||
}
|
||||
|
||||
public boolean getRedrawHint() {
|
||||
@ -862,7 +867,6 @@ public class PanZoomController
|
||||
}
|
||||
|
||||
private boolean animatedZoomTo(RectF zoomToRect) {
|
||||
GeckoApp.mAppContext.hidePluginViews();
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
|
||||
mState = PanZoomState.ANIMATED_ZOOM;
|
||||
|
@ -56,6 +56,7 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/dom/plugins/base/android \
|
||||
-I$(topsrcdir)/gfx/skia/include/core \
|
||||
-I$(topsrcdir)/gfx/skia/include/config \
|
||||
-I$(topsrcdir)/gfx/gl \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -1709,9 +1709,9 @@ AndroidBridge::ReleaseNativeWindow(void *window)
|
||||
}
|
||||
|
||||
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
|
||||
@ -1857,3 +1857,85 @@ extern "C" {
|
||||
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 "nsIMIMEInfo.h"
|
||||
#include "nsColor.h"
|
||||
#include "gfxRect.h"
|
||||
|
||||
#include "nsIAndroidBridge.h"
|
||||
|
||||
@ -341,7 +342,7 @@ public:
|
||||
|
||||
void *AcquireNativeWindow(jobject surface);
|
||||
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 UnlockWindow(void *window);
|
||||
@ -378,6 +379,11 @@ public:
|
||||
void EnableNetworkNotifications();
|
||||
void DisableNetworkNotifications();
|
||||
|
||||
jobject CreateSurface();
|
||||
void DestroySurface(jobject surface);
|
||||
void ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend);
|
||||
void HideSurface(jobject surface);
|
||||
|
||||
protected:
|
||||
static AndroidBridge *sBridge;
|
||||
|
||||
|
155
widget/android/AndroidMediaLayer.cpp
Normal file
155
widget/android/AndroidMediaLayer.cpp
Normal file
@ -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 */
|
96
widget/android/AndroidMediaLayer.h
Normal file
96
widget/android/AndroidMediaLayer.h
Normal file
@ -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 \
|
||||
AndroidGraphicBuffer.cpp \
|
||||
AndroidJNI.cpp \
|
||||
AndroidMediaLayer.cpp \
|
||||
nsWindow.cpp \
|
||||
nsLookAndFeel.cpp \
|
||||
nsScreenManagerAndroid.cpp \
|
||||
|
@ -1019,7 +1019,7 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
||||
if (surface) {
|
||||
sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(surface);
|
||||
if (sNativeWindow) {
|
||||
AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, AndroidBridge::WINDOW_FORMAT_RGB_565);
|
||||
AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, 0, 0, AndroidBridge::WINDOW_FORMAT_RGB_565);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user