mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 670930 - Use asynchronous direct texturing on Android when available
This commit is contained in:
parent
c95ce8cb7c
commit
f2138c4d9f
@ -138,6 +138,8 @@ public class GeckoAppShell
|
||||
public static native void notifySmsReceived(String aSender, String aBody, long aTimestamp);
|
||||
public static native ByteBuffer allocateDirectBuffer(long size);
|
||||
public static native void freeDirectBuffer(ByteBuffer buf);
|
||||
public static native void bindWidgetTexture();
|
||||
public static native boolean testDirectTexture();
|
||||
|
||||
// A looper thread, accessed by GeckoAppShell.getHandler
|
||||
private static class LooperThread extends Thread {
|
||||
@ -425,6 +427,14 @@ public class GeckoAppShell
|
||||
|
||||
Log.i(LOGTAG, "post native init");
|
||||
|
||||
// If we have direct texture available, use it
|
||||
if (GeckoAppShell.testDirectTexture()) {
|
||||
Log.i(LOGTAG, "Using direct texture for widget layer");
|
||||
GeckoApp.mAppContext.getSoftwareLayerClient().installWidgetLayer();
|
||||
} else {
|
||||
Log.i(LOGTAG, "Falling back to traditional texture upload");
|
||||
}
|
||||
|
||||
// Tell Gecko where the target byte buffer is for rendering
|
||||
GeckoAppShell.setSoftwareLayerClient(GeckoApp.mAppContext.getSoftwareLayerClient());
|
||||
|
||||
|
@ -107,6 +107,7 @@ JAVAFILES = \
|
||||
gfx/TextureReaper.java \
|
||||
gfx/TileLayer.java \
|
||||
gfx/ViewportMetrics.java \
|
||||
gfx/WidgetTileLayer.java \
|
||||
ui/PanZoomController.java \
|
||||
$(NULL)
|
||||
|
||||
|
@ -45,6 +45,7 @@ import org.mozilla.gecko.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.LayerRenderer;
|
||||
import org.mozilla.gecko.gfx.PointUtils;
|
||||
import org.mozilla.gecko.gfx.SingleTileLayer;
|
||||
import org.mozilla.gecko.gfx.WidgetTileLayer;
|
||||
import org.mozilla.gecko.FloatUtils;
|
||||
import org.mozilla.gecko.GeckoApp;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
@ -76,7 +77,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
||||
private IntSize mScreenSize, mViewportSize;
|
||||
private IntSize mBufferSize;
|
||||
private ByteBuffer mBuffer;
|
||||
private final SingleTileLayer mTileLayer;
|
||||
private Layer mTileLayer;
|
||||
|
||||
/* The viewport rect that Gecko is currently displaying. */
|
||||
private ViewportMetrics mGeckoViewport;
|
||||
@ -125,6 +126,10 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
||||
}
|
||||
}
|
||||
|
||||
public void installWidgetLayer() {
|
||||
mTileLayer = new WidgetTileLayer(mCairoImage);
|
||||
}
|
||||
|
||||
/** Attaches the root layer to the layer controller so that Gecko appears. */
|
||||
@Override
|
||||
public void setLayerController(LayerController layerController) {
|
||||
@ -188,7 +193,9 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
||||
updateViewport(metadata, !mUpdateViewportOnEndDraw);
|
||||
mUpdateViewportOnEndDraw = false;
|
||||
Rect rect = new Rect(x, y, x + width, y + height);
|
||||
mTileLayer.invalidate(rect);
|
||||
|
||||
if (mTileLayer instanceof SingleTileLayer)
|
||||
((SingleTileLayer)mTileLayer).invalidate(rect);
|
||||
} finally {
|
||||
endTransaction(mTileLayer);
|
||||
}
|
||||
|
@ -53,24 +53,24 @@ public abstract class LayerClient {
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility function for calling TileLayer.beginTransaction with the
|
||||
* A utility function for calling Layer.beginTransaction with the
|
||||
* appropriate LayerView.
|
||||
*/
|
||||
public void beginTransaction(TileLayer aTileLayer) {
|
||||
public void beginTransaction(Layer aLayer) {
|
||||
if (mLayerController != null) {
|
||||
LayerView view = mLayerController.getView();
|
||||
if (view != null) {
|
||||
aTileLayer.beginTransaction(view);
|
||||
aLayer.beginTransaction(view);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aTileLayer.beginTransaction();
|
||||
aLayer.beginTransaction();
|
||||
}
|
||||
|
||||
// Included for symmetry.
|
||||
public void endTransaction(TileLayer aTileLayer) {
|
||||
aTileLayer.endTransaction();
|
||||
public void endTransaction(Layer aLayer) {
|
||||
aLayer.endTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
|
116
mobile/android/base/gfx/WidgetTileLayer.java
Normal file
116
mobile/android/base/gfx/WidgetTileLayer.java
Normal file
@ -0,0 +1,116 @@
|
||||
/* -*- 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.gfx.LayerController;
|
||||
import org.mozilla.gecko.gfx.SingleTileLayer;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import android.opengl.GLES11;
|
||||
import android.opengl.GLES11Ext;
|
||||
import android.graphics.RectF;
|
||||
import android.util.Log;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* Encapsulates the logic needed to draw the single-tiled Gecko texture
|
||||
*/
|
||||
public class WidgetTileLayer extends Layer {
|
||||
|
||||
private int[] mTextureIDs;
|
||||
private CairoImage mImage;
|
||||
|
||||
public WidgetTileLayer(CairoImage image) {
|
||||
mImage = image;
|
||||
}
|
||||
|
||||
protected boolean initialized() { return mTextureIDs != null; }
|
||||
|
||||
@Override
|
||||
public IntSize getSize() { return mImage.getSize(); }
|
||||
|
||||
protected void bindAndSetGLParameters() {
|
||||
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIDs[0]);
|
||||
GLES11.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
|
||||
GLES11.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
if (mTextureIDs != null)
|
||||
TextureReaper.get().add(mTextureIDs);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performUpdates(GL10 gl) {
|
||||
super.performUpdates(gl);
|
||||
|
||||
if (mTextureIDs == null) {
|
||||
mTextureIDs = new int[1];
|
||||
GLES11.glGenTextures(1, mTextureIDs, 0);
|
||||
}
|
||||
|
||||
bindAndSetGLParameters();
|
||||
GeckoAppShell.bindWidgetTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(RenderContext context) {
|
||||
// mTextureIDs may be null here during startup if Layer.java's draw method
|
||||
// failed to acquire the transaction lock and call performUpdates.
|
||||
if (!initialized())
|
||||
return;
|
||||
|
||||
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIDs[0]);
|
||||
|
||||
RectF bounds;
|
||||
int[] cropRect;
|
||||
IntSize size = getSize();
|
||||
RectF viewport = context.viewport;
|
||||
|
||||
bounds = getBounds(context, new FloatSize(size));
|
||||
cropRect = new int[] { 0, size.height, size.width, -size.height };
|
||||
bounds.offset(-viewport.left, -viewport.top);
|
||||
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect,
|
||||
0);
|
||||
|
||||
float top = viewport.height() - (bounds.top + bounds.height());
|
||||
GLES11Ext.glDrawTexfOES(bounds.left, top, 0.0f, bounds.width(), bounds.height());
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,8 @@ SHELL_WRAPPER1(cameraCallbackBridge, jbyteArray)
|
||||
SHELL_WRAPPER1(notifyUriVisited, jstring)
|
||||
SHELL_WRAPPER3(notifyBatteryChange, jdouble, jboolean, jdouble);
|
||||
SHELL_WRAPPER3(notifySmsReceived, jstring, jstring, jlong);
|
||||
SHELL_WRAPPER0(bindWidgetTexture);
|
||||
SHELL_WRAPPER0_WITH_RETURN(testDirectTexture, bool);
|
||||
|
||||
static void * xul_handle = NULL;
|
||||
static time_t apk_mtime = 0;
|
||||
@ -704,6 +706,8 @@ loadLibs(const char *apkName)
|
||||
GETFUNC(notifyUriVisited);
|
||||
GETFUNC(notifyBatteryChange);
|
||||
GETFUNC(notifySmsReceived);
|
||||
GETFUNC(bindWidgetTexture);
|
||||
GETFUNC(testDirectTexture);
|
||||
#undef GETFUNC
|
||||
sStartupTimeline = (uint64_t *)__wrap_dlsym(xul_handle, "_ZN7mozilla15StartupTimeline16sStartupTimelineE");
|
||||
gettimeofday(&t1, 0);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "nsString.h"
|
||||
|
||||
#include "AndroidBridge.h"
|
||||
#include "AndroidGraphicBuffer.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <pthread.h>
|
||||
@ -88,6 +89,11 @@ extern "C" {
|
||||
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyUriVisited(JNIEnv *, jclass, jstring uri);
|
||||
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyBatteryChange(JNIEnv* jenv, jclass, jdouble, jboolean, jdouble);
|
||||
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifySmsReceived(JNIEnv* jenv, jclass, jstring, jstring, jlong);
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_bindWidgetTexture(JNIEnv* jenv, jclass);
|
||||
NS_EXPORT bool JNICALL Java_org_mozilla_gecko_GeckoAppShell_testDirectTexture(JNIEnv* jenv, jclass);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -278,3 +284,19 @@ Java_org_mozilla_gecko_GeckoAppShell_notifySmsReceived(JNIEnv* jenv, jclass,
|
||||
nsCOMPtr<nsIRunnable> runnable = new NotifySmsReceivedRunnable(message);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
}
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
|
||||
NS_EXPORT void JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_bindWidgetTexture(JNIEnv* jenv, jclass)
|
||||
{
|
||||
nsWindow::BindToTexture();
|
||||
}
|
||||
|
||||
NS_EXPORT bool JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_testDirectTexture(JNIEnv* jenv, jclass)
|
||||
{
|
||||
return nsWindow::HasDirectTexture();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -61,6 +61,8 @@ CPPSRCS = \
|
||||
nsAppShell.cpp \
|
||||
AndroidJavaWrappers.cpp \
|
||||
AndroidBridge.cpp \
|
||||
AndroidDirectTexture.cpp \
|
||||
AndroidGraphicBuffer.cpp \
|
||||
AndroidJNI.cpp \
|
||||
nsWindow.cpp \
|
||||
nsLookAndFeel.cpp \
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <android/log.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
@ -92,6 +93,20 @@ static gfxIntSize gAndroidScreenBounds;
|
||||
bool nsWindow::sAccessibilityEnabled = false;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "AndroidDirectTexture.h"
|
||||
|
||||
static AndroidDirectTexture* sDirectTexture = new AndroidDirectTexture(2048, 2048,
|
||||
AndroidGraphicBuffer::UsageSoftwareWrite | AndroidGraphicBuffer::UsageTexture,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
|
||||
static bool sHasDirectTexture = true;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class ContentCreationNotifier;
|
||||
static nsCOMPtr<ContentCreationNotifier> gContentCreationNotifier;
|
||||
// A helper class to send updates when content processes
|
||||
@ -808,6 +823,53 @@ nsWindow::GetThebesSurface()
|
||||
return new gfxImageSurface(gfxIntSize(5,5), gfxImageSurface::ImageFormatRGB24);
|
||||
}
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
|
||||
void
|
||||
nsWindow::BindToTexture()
|
||||
{
|
||||
sDirectTexture->Bind();
|
||||
}
|
||||
|
||||
bool
|
||||
nsWindow::HasDirectTexture()
|
||||
{
|
||||
// If we already tested, return early
|
||||
if (!sHasDirectTexture)
|
||||
return false;
|
||||
|
||||
AndroidGraphicBuffer* buffer = new AndroidGraphicBuffer(512, 512,
|
||||
AndroidGraphicBuffer::UsageSoftwareWrite | AndroidGraphicBuffer::UsageTexture,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
|
||||
unsigned char* bits = NULL;
|
||||
if (!buffer->Lock(AndroidGraphicBuffer::UsageSoftwareWrite, &bits) || !bits) {
|
||||
ALOG("failed to lock graphic buffer");
|
||||
buffer->Unlock();
|
||||
sHasDirectTexture = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!buffer->Unlock()) {
|
||||
ALOG("failed to unlock graphic buffer");
|
||||
sHasDirectTexture = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!buffer->Reallocate(1024, 1024, gfxASurface::ImageFormatRGB16_565)) {
|
||||
ALOG("failed to reallocate graphic buffer");
|
||||
sHasDirectTexture = false;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
delete buffer;
|
||||
|
||||
return sHasDirectTexture;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
||||
{
|
||||
@ -1111,17 +1173,39 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
||||
client.BeginDrawing();
|
||||
|
||||
nsAutoString metadata;
|
||||
unsigned char *bits = client.LockBufferBits();
|
||||
unsigned char *bits = NULL;
|
||||
if (sHasDirectTexture) {
|
||||
if ((sDirectTexture->Width() != gAndroidBounds.width ||
|
||||
sDirectTexture->Height() != gAndroidBounds.height) &&
|
||||
gAndroidBounds.width != 0 && gAndroidBounds.height != 0) {
|
||||
sDirectTexture->Reallocate(gAndroidBounds.width, gAndroidBounds.height);
|
||||
}
|
||||
|
||||
sDirectTexture->Lock(AndroidGraphicBuffer::UsageSoftwareWrite, &bits);
|
||||
} else {
|
||||
bits = client.LockBufferBits();
|
||||
}
|
||||
if (!bits) {
|
||||
ALOG("### Failed to lock buffer");
|
||||
|
||||
if (sHasDirectTexture) {
|
||||
sDirectTexture->Unlock();
|
||||
} else {
|
||||
client.UnlockBuffer();
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxImageSurface> targetSurface =
|
||||
new gfxImageSurface(bits, gfxIntSize(gAndroidBounds.width, gAndroidBounds.height), gAndroidBounds.width * 2,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
if (targetSurface->CairoStatus()) {
|
||||
ALOG("### Failed to create a valid surface from the bitmap");
|
||||
} else {
|
||||
if (sHasDirectTexture) {
|
||||
// XXX: lock only the dirty rect above and pass it in here
|
||||
DrawTo(targetSurface);
|
||||
} else {
|
||||
DrawTo(targetSurface, ae->Rect());
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIAndroidDrawMetadataProvider> metadataProvider =
|
||||
@ -1130,8 +1214,12 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
||||
metadataProvider->GetDrawMetadata(metadata);
|
||||
}
|
||||
}
|
||||
if (sHasDirectTexture) {
|
||||
sDirectTexture->Unlock();
|
||||
} else {
|
||||
client.UnlockBuffer();
|
||||
}
|
||||
}
|
||||
client.EndDrawing(ae->Rect(), metadata);
|
||||
return;
|
||||
#endif
|
||||
|
@ -177,6 +177,11 @@ public:
|
||||
static bool sAccessibilityEnabled;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_JAVA_COMPOSITOR
|
||||
static void BindToTexture();
|
||||
static bool HasDirectTexture();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void BringToFront();
|
||||
nsWindow *FindTopLevel();
|
||||
|
Loading…
Reference in New Issue
Block a user