Merge "surfaceflinger: call into hardware composer to blank screen"
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 4f32146..e12d163 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -66,13 +66,11 @@
eMatrixChanged = 0x00000010,
eTransparentRegionChanged = 0x00000020,
eVisibilityChanged = 0x00000040,
- eFreezeTintChanged = 0x00000080,
eCropChanged = 0x00000100,
};
enum {
eLayerHidden = 0x01,
- eLayerFrozen = 0x02,
eLayerDither = 0x04,
eLayerFilter = 0x08,
eLayerBlurFreeze = 0x10
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 50bdf71..7b8873a 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -65,13 +65,10 @@
status_t setSize(uint32_t w, uint32_t h);
status_t hide();
status_t show(int32_t layer = -1);
- status_t freeze();
- status_t unfreeze();
status_t setFlags(uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(const Region& transparent);
status_t setAlpha(float alpha=1.0f);
status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
- status_t setFreezeTint(uint32_t tint);
status_t setCrop(const Rect& crop);
static status_t writeSurfaceToParcel(
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 3bd10de..9f3ef35 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -93,12 +93,6 @@
//! Close a composer transaction on all active SurfaceComposerClients.
static void closeGlobalTransaction(bool synchronous = false);
-
- //! Freeze the specified display but not transactions.
- static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);
-
- //! Resume updates on the specified display.
- static status_t unfreezeDisplay(DisplayID dpy, uint32_t flags = 0);
//! Set the orientation of the given display
static int setOrientation(DisplayID dpy, int orientation, uint32_t flags);
@@ -117,13 +111,10 @@
status_t hide(SurfaceID id);
status_t show(SurfaceID id, int32_t layer = -1);
- status_t freeze(SurfaceID id);
- status_t unfreeze(SurfaceID id);
status_t setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(SurfaceID id, const Region& transparent);
status_t setLayer(SurfaceID id, int32_t layer);
status_t setAlpha(SurfaceID id, float alpha=1.0f);
- status_t setFreezeTint(SurfaceID id, uint32_t tint);
status_t setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
status_t setPosition(SurfaceID id, float x, float y);
status_t setSize(SurfaceID id, uint32_t w, uint32_t h);
diff --git a/include/media/hardware/CryptoAPI.h b/include/media/hardware/CryptoAPI.h
index 810a443..44a0040 100644
--- a/include/media/hardware/CryptoAPI.h
+++ b/include/media/hardware/CryptoAPI.h
@@ -70,7 +70,9 @@
// At the java level these special errors will then trigger a
// MediaCodec.CryptoException that gives clients access to both
// the error code and the errorDetailMsg.
- virtual status_t decrypt(
+ // Returns a non-negative result to indicate the number of bytes written
+ // to the dstPtr, or a negative result to indicate an error.
+ virtual ssize_t decrypt(
bool secure,
const uint8_t key[16],
const uint8_t iv[16],
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 9151c11..239dd87 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -36,7 +36,7 @@
layer_state_t()
: surface(0), what(0),
x(0), y(0), z(0), w(0), h(0),
- alpha(0), tint(0), flags(0), mask(0),
+ alpha(0), flags(0), mask(0),
reserved(0)
{
matrix.dsdx = matrix.dtdy = 1.0f;
@@ -61,7 +61,6 @@
uint32_t w;
uint32_t h;
float alpha;
- uint32_t tint;
uint8_t flags;
uint8_t mask;
uint8_t reserved;
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index e39a5b7..a89393f 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -72,11 +72,11 @@
//! returns number of items in the vector
inline size_t size() const { return VectorImpl::size(); }
- //! returns wether or not the vector is empty
+ //! returns whether or not the vector is empty
inline bool isEmpty() const { return VectorImpl::isEmpty(); }
//! returns how many items can be stored without reallocating the backing store
inline size_t capacity() const { return VectorImpl::capacity(); }
- //! setst the capacity. capacity can never be reduced less than size()
+ //! sets the capacity. capacity can never be reduced less than size()
inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
/*!
@@ -102,12 +102,12 @@
const TYPE& mirrorItemAt(ssize_t index) const;
/*!
- * modifing the array
+ * modifying the array
*/
//! copy-on write support, grants write access to an item
TYPE& editItemAt(size_t index);
- //! grants right acces to the top of the stack (last element)
+ //! grants right access to the top of the stack (last element)
TYPE& editTop();
/*!
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index d7590f0..b9cbfa6 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -122,18 +122,6 @@
const sp<SurfaceComposerClient>& client(mClient);
return client->show(mToken, layer);
}
-status_t SurfaceControl::freeze() {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->freeze(mToken);
-}
-status_t SurfaceControl::unfreeze() {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->unfreeze(mToken);
-}
status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
status_t err = validate();
if (err < 0) return err;
@@ -158,12 +146,6 @@
const sp<SurfaceComposerClient>& client(mClient);
return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
}
-status_t SurfaceControl::setFreezeTint(uint32_t tint) {
- status_t err = validate();
- if (err < 0) return err;
- const sp<SurfaceComposerClient>& client(mClient);
- return client->setFreezeTint(mToken, tint);
-}
status_t SurfaceControl::setCrop(const Rect& crop) {
status_t err = validate();
if (err < 0) return err;
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 8fa2167..b1bd78b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -121,9 +121,6 @@
float alpha);
status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,
float dsdx, float dtdx, float dsdy, float dtdy);
- status_t setFreezeTint(
- const sp<SurfaceComposerClient>& client, SurfaceID id,
- uint32_t tint);
status_t setOrientation(int orientation);
status_t setCrop(const sp<SurfaceComposerClient>& client, SurfaceID id,
const Rect& crop);
@@ -271,17 +268,6 @@
return NO_ERROR;
}
-status_t Composer::setFreezeTint(const sp<SurfaceComposerClient>& client,
- SurfaceID id, uint32_t tint) {
- Mutex::Autolock _l(mLock);
- layer_state_t* s = getLayerStateLocked(client, id);
- if (!s)
- return BAD_INDEX;
- s->what |= ISurfaceComposer::eFreezeTintChanged;
- s->tint = tint;
- return NO_ERROR;
-}
-
status_t Composer::setOrientation(int orientation) {
Mutex::Autolock _l(mLock);
mOrientation = orientation;
@@ -415,10 +401,6 @@
return getComposer().setCrop(this, id, crop);
}
-status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint) {
- return getComposer().setFreezeTint(this, id, tint);
-}
-
status_t SurfaceComposerClient::setPosition(SurfaceID id, float x, float y) {
return getComposer().setPosition(this, id, x, y);
}
@@ -443,18 +425,6 @@
ISurfaceComposer::eLayerHidden);
}
-status_t SurfaceComposerClient::freeze(SurfaceID id) {
- return getComposer().setFlags(this, id,
- ISurfaceComposer::eLayerFrozen,
- ISurfaceComposer::eLayerFrozen);
-}
-
-status_t SurfaceComposerClient::unfreeze(SurfaceID id) {
- return getComposer().setFlags(this, id,
- 0,
- ISurfaceComposer::eLayerFrozen);
-}
-
status_t SurfaceComposerClient::setFlags(SurfaceID id, uint32_t flags,
uint32_t mask) {
return getComposer().setFlags(this, id, flags, mask);
@@ -542,20 +512,6 @@
// ----------------------------------------------------------------------------
-status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
- // This has been made a no-op because it can cause Gralloc buffer deadlocks.
- return NO_ERROR;
-}
-
-status_t SurfaceComposerClient::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
- // This has been made a no-op because it can cause Gralloc buffer deadlocks.
- return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
ScreenshotClient::ScreenshotClient()
: mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
}
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 9c76e6e..ed6b73e 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -338,14 +338,14 @@
sp<Fence> mergedFence = Fence::merge(
String8("SurfaceTexture merged release"),
mEGLSlots[mCurrentTexture].mReleaseFence, fence);
- if (mergedFence.get()) {
+ if (!mergedFence.get()) {
ALOGE("failed to merge release fences");
// synchronization is broken, the best we can do is hope fences
// signal in order so the new fence will act like a union
mEGLSlots[mCurrentTexture].mReleaseFence = fence;
- } else {
- mEGLSlots[mCurrentTexture].mReleaseFence = mergedFence;
+ return;
}
+ mEGLSlots[mCurrentTexture].mReleaseFence = mergedFence;
}
}
diff --git a/opengl/tools/glgen/gen b/opengl/tools/glgen/gen
index 31f4190..3359a22 100755
--- a/opengl/tools/glgen/gen
+++ b/opengl/tools/glgen/gen
@@ -12,6 +12,7 @@
mkdir -p out/com/google/android/gles_jni
mkdir -p out/android/app
mkdir -p out/android/graphics
+mkdir -p out/android/view
mkdir -p out/android/opengl
mkdir -p out/android/content
mkdir -p out/android/content/pm
@@ -24,15 +25,33 @@
echo "package android.app; import android.content.pm.IPackageManager; public class AppGlobals { public static IPackageManager getPackageManager() { return null;} }" > out/android/app/AppGlobals.java
# echo "package android.content; import android.content.pm.PackageManager; public interface Context { public PackageManager getPackageManager(); }" > out/android/content/Context.java
echo "package android.content.pm; public class ApplicationInfo {public int targetSdkVersion;}" > out/android/content/pm/ApplicationInfo.java
-echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java
+echo "package android.content.pm; public interface IPackageManager {ApplicationInfo getApplicationInfo(java.lang.String packageName, int flags, java.lang.String userId) throws android.os.RemoteException;}" > out/android/content/pm/IPackageManager.java
echo "package android.os; public class Build {public static class VERSION_CODES { public static final int CUPCAKE = 3;}; }" > out/android/os/Build.java
+echo "package android.os; public class UserId {public static String myUserId() { return \"\"; } }" > out/android/os/UserId.java
echo "package android.os; public class RemoteException extends Exception {}" > out/android/os/RemoteException.java
echo "package android.util; public class Log {public static void w(String a, String b) {} public static void e(String a, String b) {}}" > out/android/util/Log.java
+echo "package android.opengl; public abstract class EGLObjectHandle { public int getHandle() { return 0; } }" > out/android/opengl/EGLObjectHandle.java
+echo "package android.opengl; public class EGLSurface extends EGLObjectHandle { }" > out/android/opengl/EGLSurface.java
+echo "package android.opengl; public class EGLContext extends EGLObjectHandle { }" > out/android/opengl/EGLContext.java
+echo "package android.opengl; public class EGLDisplay extends EGLObjectHandle { }" > out/android/opengl/EGLDisplay.java
+echo "package android.opengl; public class EGLConfig extends EGLObjectHandle { }" > out/android/opengl/EGLConfig.java
+
+
+echo "package android.graphics;" > out/android/graphics/SurfaceTexture.java
+echo "public interface SurfaceTexture {}" >> out/android/graphics/SurfaceTexture.java
+echo "package android.view;" > out/android/view/SurfaceView.java
+echo "public interface SurfaceView { SurfaceHolder getHolder(); }" >> out/android/view/SurfaceView.java
+echo "package android.view;" > out/android/view/Surface.java
+echo "public interface Surface {}" >> out/android/view/Surface.java
+echo "package android.view;" > out/android/view/SurfaceHolder.java
+echo "public interface SurfaceHolder { Surface getSurface(); }" >> out/android/view/SurfaceHolder.java
+
+
GLFILE=out/javax/microedition/khronos/opengles/GL.java
cp stubs/jsr239/GLHeader.java-if $GLFILE
-GLGEN_FILES="CFunc.java CType.java CodeEmitter.java GenerateGL.java GenerateGLES.java GLESCodeEmitter.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java"
+GLGEN_FILES="CFunc.java CType.java CodeEmitter.java EGLCodeEmitter.java GenerateEGL.java GenerateGL.java GenerateGLES.java GLESCodeEmitter.java JFunc.java JniCodeEmitter.java JType.java Jsr239CodeEmitter.java ParameterChecker.java"
pushd src > /dev/null
javac ${GLGEN_FILES}
@@ -59,11 +78,19 @@
exit $JAVA_RESULT
fi
+echo "Generating static EGL 1.4 bindings"
+java -classpath src GenerateEGL
+JAVA_RESULT=$?
+if [ $JAVA_RESULT -ne 0 ]; then
+ echo "Could not run GenerateEGL."
+ exit $JAVA_RESULT
+fi
+
rm src/*.class
pushd out > /dev/null
mkdir classes
-javac -d classes com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java android/opengl/GLES20.java
+javac -d classes android/opengl/EGL14.java com/google/android/gles_jni/GLImpl.java javax/microedition/khronos/opengles/GL10.java javax/microedition/khronos/opengles/GL10Ext.java javax/microedition/khronos/opengles/GL11.java javax/microedition/khronos/opengles/GL11Ext.java javax/microedition/khronos/opengles/GL11ExtensionPack.java android/opengl/GLES10.java android/opengl/GLES10Ext.java android/opengl/GLES11.java android/opengl/GLES11Ext.java android/opengl/GLES20.java
popd > /dev/null
JAVA_RESULT=$?
if [ $JAVA_RESULT -ne 0 ]; then
@@ -90,6 +117,7 @@
if cmp -s $1/$3 $2/$3 ; then
echo "# " $3 unchanged
else
+ echo "# " $3 changed
if [ $SAID_PLEASE == "0" ] ; then
echo Please evaluate the following commands:
echo
@@ -101,18 +129,18 @@
fi
}
-compareGenerated ../../../core/jni generated/C com_google_android_gles_jni_GLImpl.cpp
-compareGenerated ../../java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java
+compareGenerated ../../../../base/core/jni generated/C com_google_android_gles_jni_GLImpl.cpp
+compareGenerated ../../../../base/opengl/java/com/google/android/gles_jni generated/com/google/android/gles_jni GLImpl.java
for x in GL.java GL10.java GL10Ext.java GL11.java GL11Ext.java GL11ExtensionPack.java
do
- compareGenerated ../../java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x
+ compareGenerated ../../../../base/opengl/java/javax/microedition/khronos/opengles generated/javax/microedition/khronos/opengles $x
done
-for x in GLES10 GLES10Ext GLES11 GLES11Ext GLES20
+for x in EGL14 GLES10 GLES10Ext GLES11 GLES11Ext GLES20
do
- compareGenerated ../../java/android/opengl generated/android/opengl ${x}.java
- compareGenerated ../../../core/jni generated/C android_opengl_${x}.cpp
+ compareGenerated ../../../../base/opengl/java/android/opengl generated/android/opengl ${x}.java
+ compareGenerated ../../../../base/core/jni generated/C android_opengl_${x}.cpp
done
if [ $KEEP_GENERATED == "0" ] ; then
diff --git a/opengl/tools/glgen/specs/egl/EGL14.spec b/opengl/tools/glgen/specs/egl/EGL14.spec
new file mode 100644
index 0000000..828e114
--- /dev/null
+++ b/opengl/tools/glgen/specs/egl/EGL14.spec
@@ -0,0 +1,33 @@
+EGLint eglGetError ( void )
+EGLDisplay eglGetDisplay ( EGLNativeDisplayType display_id )
+EGLBoolean eglInitialize ( EGLDisplay dpy, EGLint *major, EGLint *minor )
+EGLBoolean eglTerminate ( EGLDisplay dpy )
+const char * eglQueryString ( EGLDisplay dpy, EGLint name )
+EGLBoolean eglGetConfigs ( EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config )
+EGLBoolean eglChooseConfig ( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config )
+EGLBoolean eglGetConfigAttrib ( EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value )
+EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list )
+EGLSurface eglCreatePbufferSurface ( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list )
+EGLSurface eglCreatePixmapSurface ( EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list )
+EGLBoolean eglDestroySurface ( EGLDisplay dpy, EGLSurface surface )
+EGLBoolean eglQuerySurface ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value )
+EGLBoolean eglBindAPI ( EGLenum api )
+EGLenum eglQueryAPI ( void )
+EGLBoolean eglWaitClient ( void )
+EGLBoolean eglReleaseThread ( void )
+EGLSurface eglCreatePbufferFromClientBuffer ( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list )
+EGLBoolean eglSurfaceAttrib ( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value )
+EGLBoolean eglBindTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer )
+EGLBoolean eglReleaseTexImage ( EGLDisplay dpy, EGLSurface surface, EGLint buffer )
+EGLBoolean eglSwapInterval ( EGLDisplay dpy, EGLint interval )
+EGLContext eglCreateContext ( EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list )
+EGLBoolean eglDestroyContext ( EGLDisplay dpy, EGLContext ctx )
+EGLBoolean eglMakeCurrent ( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx )
+EGLContext eglGetCurrentContext ( void )
+EGLSurface eglGetCurrentSurface ( EGLint readdraw )
+EGLDisplay eglGetCurrentDisplay ( void )
+EGLBoolean eglQueryContext ( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value )
+EGLBoolean eglWaitGL ( void )
+EGLBoolean eglWaitNative ( EGLint engine )
+EGLBoolean eglSwapBuffers ( EGLDisplay dpy, EGLSurface surface )
+EGLBoolean eglCopyBuffers ( EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target )
diff --git a/opengl/tools/glgen/specs/egl/checks.spec b/opengl/tools/glgen/specs/egl/checks.spec
new file mode 100644
index 0000000..34fb1ee
--- /dev/null
+++ b/opengl/tools/glgen/specs/egl/checks.spec
@@ -0,0 +1,13 @@
+eglInitialize check major 1 check minor 1
+eglGetConfigs check configs config_size
+eglChooseConfig check configs config_size check num_config 1 sentinel attrib_list EGL_NONE
+eglGetConfigAttrib check value 1
+//STUB function: //eglCreateWindowSurface sentinel attrib_list EGL_NONE
+eglCreatePbufferSurface sentinel attrib_list EGL_NONE
+//unsupported: eglCreatePixmapSurface sentinel attrib_list EGL_NONE
+eglCreatePixmapSurface unsupported
+eglCopyBuffers unsupported
+eglQuerySurface check value 1
+eglCreatePbufferFromClientBuffer sentinel attrib_list EGL_NONE
+eglCreateContext sentinel attrib_list EGL_NONE
+eglQueryContext check value 1
diff --git a/opengl/tools/glgen/src/CFunc.java b/opengl/tools/glgen/src/CFunc.java
index 4847694..a192c00 100644
--- a/opengl/tools/glgen/src/CFunc.java
+++ b/opengl/tools/glgen/src/CFunc.java
@@ -28,6 +28,7 @@
boolean hasPointerArg = false;
boolean hasTypedPointerArg = false;
+ boolean hasEGLHandleArg = false;
public CFunc(String original) {
this.original = original;
@@ -63,6 +64,9 @@
if (argType.isTypedPointer()) {
hasTypedPointerArg = true;
}
+ if (argType.isEGLHandle()) {
+ hasEGLHandleArg = true;
+ }
}
public int getNumArgs() {
@@ -95,6 +99,10 @@
return hasTypedPointerArg;
}
+ public boolean hasEGLHandleArg() {
+ return hasEGLHandleArg;
+ }
+
@Override
public String toString() {
String s = "Function " + fname + " returns " + ftype + ": ";
diff --git a/opengl/tools/glgen/src/CType.java b/opengl/tools/glgen/src/CType.java
index e0f0ca6..92950ea 100644
--- a/opengl/tools/glgen/src/CType.java
+++ b/opengl/tools/glgen/src/CType.java
@@ -53,6 +53,16 @@
return isPointer;
}
+ public boolean isEGLHandle() {
+ if(baseType.equals("EGLContext")
+ || baseType.equals("EGLConfig")
+ || baseType.equals("EGLSurface")
+ || baseType.equals("EGLDisplay")) {
+ return true;
+ }
+ return false;
+ }
+
boolean isVoid() {
String baseType = getBaseType();
return baseType.equals("GLvoid") ||
diff --git a/opengl/tools/glgen/src/EGLCodeEmitter.java b/opengl/tools/glgen/src/EGLCodeEmitter.java
new file mode 100644
index 0000000..1691b65
--- /dev/null
+++ b/opengl/tools/glgen/src/EGLCodeEmitter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.PrintStream;
+
+/**
+ * Emits a Java interface and Java & C implementation for a C function.
+ *
+ * <p> The Java interface will have Buffer and array variants for functions that
+ * have a typed pointer argument. The array variant will convert a single "<type> *data"
+ * argument to a pair of arguments "<type>[] data, int offset".
+ */
+public class EGLCodeEmitter extends JniCodeEmitter {
+
+ PrintStream mJavaImplStream;
+ PrintStream mCStream;
+
+ PrintStream mJavaInterfaceStream;
+
+ /**
+ */
+ public EGLCodeEmitter(String classPathName,
+ ParameterChecker checker,
+ PrintStream javaImplStream,
+ PrintStream cStream) {
+ mClassPathName = classPathName;
+ mChecker = checker;
+
+ mJavaImplStream = javaImplStream;
+ mCStream = cStream;
+ mUseContextPointer = false;
+ mUseStaticMethods = true;
+ mUseSimpleMethodNames = true;
+ mUseHideCommentForAPI = true;
+ }
+
+ public void emitCode(CFunc cfunc, String original) {
+ emitCode(cfunc, original, null, mJavaImplStream,
+ mCStream);
+ }
+
+ public void emitNativeRegistration(String nativeRegistrationName) {
+ emitNativeRegistration(nativeRegistrationName, mCStream);
+ }
+}
diff --git a/opengl/tools/glgen/src/GenerateEGL.java b/opengl/tools/glgen/src/GenerateEGL.java
new file mode 100644
index 0000000..aaa748c
--- /dev/null
+++ b/opengl/tools/glgen/src/GenerateEGL.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+
+public class GenerateEGL {
+
+ private static void copy(String filename, PrintStream out) throws IOException {
+ BufferedReader br = new BufferedReader(new FileReader(filename));
+ String s;
+ while ((s = br.readLine()) != null) {
+ out.println(s);
+ }
+ }
+
+ private static void emit(EGLCodeEmitter emitter,
+ BufferedReader specReader,
+ PrintStream glStream,
+ PrintStream cStream) throws Exception {
+ String s = null;
+ while ((s = specReader.readLine()) != null) {
+ if (s.trim().startsWith("//")) {
+ continue;
+ }
+
+ CFunc cfunc = CFunc.parseCFunc(s);
+
+ String fname = cfunc.getName();
+ String stubRoot = "stubs/egl/" + fname;
+ String javaPath = stubRoot + ".java";
+ File f = new File(javaPath);
+ if (f.exists()) {
+ System.out.println("Special-casing function " + fname);
+ copy(javaPath, glStream);
+ copy(stubRoot + ".cpp", cStream);
+
+ // Register native function names
+ // This should be improved to require fewer discrete files
+ String filename = stubRoot + ".nativeReg";
+ BufferedReader br =
+ new BufferedReader(new FileReader(filename));
+ String nfunc;
+ while ((nfunc = br.readLine()) != null) {
+ emitter.addNativeRegistration(nfunc);
+ }
+ } else {
+ emitter.emitCode(cfunc, s);
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ int aidx = 0;
+ while ((aidx < args.length) && (args[aidx].charAt(0) == '-')) {
+ switch (args[aidx].charAt(1)) {
+ default:
+ System.err.println("Unknown flag: " + args[aidx]);
+ System.exit(1);
+ }
+
+ aidx++;
+ }
+
+ BufferedReader checksReader =
+ new BufferedReader(new FileReader("specs/egl/checks.spec"));
+ ParameterChecker checker = new ParameterChecker(checksReader);
+
+
+ BufferedReader specReader =
+ new BufferedReader(new FileReader("specs/egl/EGL14.spec"));
+
+ String egljFilename = "android/opengl/EGL14.java";
+ String eglcFilename = "android_opengl_EGL14.cpp";
+ PrintStream egljStream =
+ new PrintStream(new FileOutputStream("out/" + egljFilename));
+ PrintStream eglcStream =
+ new PrintStream(new FileOutputStream("out/" + eglcFilename));
+ egljStream.println("/*");
+ eglcStream.println("/*");
+ copy("stubs/egl/EGL14Header.java-if", egljStream);
+ copy("stubs/egl/EGL14cHeader.cpp", eglcStream);
+ EGLCodeEmitter emitter = new EGLCodeEmitter(
+ "android/opengl/EGL14",
+ checker, egljStream, eglcStream);
+ emit(emitter, specReader, egljStream, eglcStream);
+ emitter.emitNativeRegistration("register_android_opengl_jni_EGL14");
+ egljStream.println("}");
+ egljStream.close();
+ eglcStream.close();
+ }
+}
diff --git a/opengl/tools/glgen/src/JType.java b/opengl/tools/glgen/src/JType.java
index deb2f01..3f7cb73 100644
--- a/opengl/tools/glgen/src/JType.java
+++ b/opengl/tools/glgen/src/JType.java
@@ -48,6 +48,22 @@
typeMapping.put(new CType("char", true, true), new JType("String", false, false));
typeMapping.put(new CType("int"), new JType("int"));
+ // EGL primitive types
+ typeMapping.put(new CType("EGLint"), new JType("int"));
+ typeMapping.put(new CType("EGLBoolean"), new JType("boolean"));
+ typeMapping.put(new CType("EGLenum"), new JType("int"));
+ typeMapping.put(new CType("EGLNativePixmapType"), new JType("int"));
+ typeMapping.put(new CType("EGLNativeWindowType"), new JType("int"));
+ typeMapping.put(new CType("EGLNativeDisplayType"), new JType("int"));
+ typeMapping.put(new CType("EGLClientBuffer"), new JType("int"));
+
+ // EGL nonprimitive types
+ typeMapping.put(new CType("EGLConfig"), new JType("EGLConfig", true, false));
+ typeMapping.put(new CType("EGLContext"), new JType("EGLContext", true, false));
+ typeMapping.put(new CType("EGLDisplay"), new JType("EGLDisplay", true, false));
+ typeMapping.put(new CType("EGLSurface"), new JType("EGLSurface", true, false));
+
+
// Untyped pointers map to untyped Buffers
typeMapping.put(new CType("GLvoid", true, true),
new JType("java.nio.Buffer", true, false));
@@ -88,7 +104,7 @@
arrayTypeMapping.put(new CType("char", false, true),
new JType("byte", false, true));
arrayTypeMapping.put(new CType("GLboolean", false, true),
- new JType("boolean", false, true));
+ new JType("boolean", false, true));
arrayTypeMapping.put(new CType("GLenum", false, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLfixed", false, true), new JType("int", false, true));
@@ -103,6 +119,13 @@
arrayTypeMapping.put(new CType("GLuint", true, true), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLintptr"), new JType("int", false, true));
arrayTypeMapping.put(new CType("GLsizeiptr"), new JType("int", false, true));
+
+ //EGL typed pointers map to arrays + offsets
+ arrayTypeMapping.put(new CType("EGLint", false, true), new JType("int", false, true));
+ arrayTypeMapping.put(new CType("EGLint", true, true), new JType("int", false, true));
+ arrayTypeMapping.put(new CType("EGLConfig", false, true), new JType("EGLConfig", true, true));
+ arrayTypeMapping.put(new CType("EGLConfig", true, true), new JType("EGLConfig", true, true));
+
}
public JType() {
@@ -158,6 +181,11 @@
(baseType.indexOf("Buffer") != -1);
}
+ public boolean isEGLHandle() {
+ return !isPrimitive() &&
+ (baseType.startsWith("EGL"));
+ }
+
public static JType convert(CType ctype, boolean useArray) {
JType javaType = null;
if (useArray) {
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index 9fa2b74..af98889 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -25,6 +25,8 @@
static final boolean mUseCPlusPlus = true;
protected boolean mUseContextPointer = true;
protected boolean mUseStaticMethods = false;
+ protected boolean mUseSimpleMethodNames = false;
+ protected boolean mUseHideCommentForAPI = false;
protected String mClassPathName;
protected ParameterChecker mChecker;
protected List<String> nativeRegistrations = new ArrayList<String>();
@@ -34,7 +36,9 @@
public static String getJniName(JType jType) {
String jniName = "";
- if (jType.isClass()) {
+ if (jType.isEGLHandle()) {
+ return (jType.isArray() ? "[" : "" ) + "Landroid/opengl/" + jType.getBaseType() + ";";
+ } else if (jType.isClass()) {
return "L" + jType.getBaseType() + ";";
} else if (jType.isArray()) {
jniName = "[";
@@ -63,7 +67,6 @@
return jniName;
}
-
public void emitCode(CFunc cfunc, String original,
PrintStream javaInterfaceStream,
PrintStream javaImplStream,
@@ -96,6 +99,10 @@
if (!duplicate) {
emitJniCode(jfunc, cStream);
}
+ // Don't create IOBuffer versions of the EGL functions
+ if (cfunc.hasEGLHandleArg()) {
+ return;
+ }
}
jfunc = JFunc.convert(cfunc, false);
@@ -121,8 +128,13 @@
}
public void emitNativeDeclaration(JFunc jfunc, PrintStream out) {
- out.println(" // C function " + jfunc.getCFunc().getOriginal());
- out.println();
+ if (mUseHideCommentForAPI) {
+ out.println(" /* @hide C function " + jfunc.getCFunc().getOriginal() + " */");
+ out.println();
+ } else {
+ out.println(" // C function " + jfunc.getCFunc().getOriginal());
+ out.println();
+ }
emitFunction(jfunc, out, true, false);
}
@@ -197,15 +209,17 @@
out.println(iii + "}");
out.println(iii + "if (" + remaining + " < _needed) {");
- if (emitExceptionCheck) {
- out.println(iii + indent + "_exception = 1;");
- }
- out.println(iii + indent + "jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", " +
- "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < needed\");");
+ out.println(iii + indent + "_exception = 1;");
+ out.println(iii + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(iii + indent +
+ "_exceptionMessage = \"" +
+ (isBuffer ? "remaining()" : "length - " + offset) +
+ " < needed\";");
out.println(iii + indent + "goto exit;");
- needsExit = true;
out.println(iii + "}");
+
+ needsExit = true;
}
boolean isNullAllowed(CFunc cfunc) {
@@ -213,28 +227,70 @@
int index = 1;
if (checks != null) {
while (index < checks.length) {
- if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
+ if (checks[index].equals("nullAllowed")) {
return true;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
return false;
}
+ boolean hasCheckTest(CFunc cfunc) {
+ String[] checks = mChecker.getChecks(cfunc.getName());
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("check")) {
+ return true;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ return false;
+ }
+
+ boolean hasIfTest(CFunc cfunc) {
+ String[] checks = mChecker.getChecks(cfunc.getName());
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("ifcheck")) {
+ return true;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ return false;
+ }
+
+ int skipOneCheck(String[] checks, int index) {
+ if (checks[index].equals("return")) {
+ index += 2;
+ } else if (checks[index].startsWith("check")) {
+ index += 3;
+ } else if (checks[index].startsWith("sentinel")) {
+ index += 3;
+ } else if (checks[index].equals("ifcheck")) {
+ index += 5;
+ } else if (checks[index].equals("unsupported")) {
+ index += 1;
+ } else if (checks[index].equals("requires")) {
+ index += 2;
+ } else if (checks[index].equals("nullAllowed")) {
+ index += 1;
+ } else {
+ System.out.println("Error: unknown keyword \"" +
+ checks[index] + "\"");
+ System.exit(0);
+ }
+
+ return index;
+ }
+
String getErrorReturnValue(CFunc cfunc) {
CType returnType = cfunc.getType();
boolean isVoid = returnType.isVoid();
@@ -242,6 +298,10 @@
return null;
}
+ if (returnType.getBaseType().startsWith("EGL")) {
+ return "(" + returnType.getDeclaration() + ") 0";
+ }
+
String[] checks = mChecker.getChecks(cfunc.getName());
int index = 1;
@@ -249,20 +309,8 @@
while (index < checks.length) {
if (checks[index].equals("return")) {
return checks[index + 1];
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -277,20 +325,8 @@
while (index < checks.length) {
if (checks[index].equals("unsupported")) {
return true;
- } else if (checks[index].equals("requires")) {
- index += 2;
- } else if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -302,22 +338,10 @@
int index = 1;
if (checks != null) {
while (index < checks.length) {
- if (checks[index].equals("unsupported")) {
- index += 1;
- } else if (checks[index].equals("requires")) {
+ if (checks[index].equals("requires")) {
return checks[index+1];
- } else if (checks[index].equals("return")) {
- index += 2;
- } else if (checks[index].startsWith("check")) {
- index += 3;
- } else if (checks[index].equals("ifcheck")) {
- index += 5;
- } else if (checks[index].equals("nullAllowed")) {
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" +
- checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -345,9 +369,7 @@
continue;
}
out.println(iii + "if (" + remaining + " < " + checks[index + 2] + ") {");
- if (emitExceptionCheck) {
- out.println(iii + indent + "_exception = 1;");
- }
+ out.println(iii + indent + "_exception = 1;");
String exceptionClassName = "java/lang/IllegalArgumentException";
// If the "check" keyword was of the form
// "check_<class name>", use the class name in the
@@ -361,14 +383,19 @@
throw new RuntimeException("unknown exception abbreviation: " + abbr);
}
}
- out.println(iii + indent + "jniThrowException(_env, " +
- "\"" + exceptionClassName + "\", " +
- "\"" + (isBuffer ? "remaining()" : "length - " + offset) + " < " + checks[index + 2] + "\");");
+ out.println(iii + indent +
+ "_exceptionType = \""+exceptionClassName+"\";");
+ out.println(iii + indent +
+ "_exceptionMessage = \"" +
+ (isBuffer ? "remaining()" : "length - " +
+ offset) + " < " + checks[index + 2] +
+ " < needed\";");
out.println(iii + indent + "goto exit;");
- needsExit = true;
out.println(iii + "}");
+ needsExit = true;
+
index += 3;
} else if (checks[index].equals("ifcheck")) {
String[] matches = checks[index + 4].split(",");
@@ -388,21 +415,8 @@
lastWasIfcheck = true;
index += 5;
- } else if (checks[index].equals("return")) {
- // ignore
- index += 2;
- } else if (checks[index].equals("unsupported")) {
- // ignore
- index += 1;
- } else if (checks[index].equals("requires")) {
- // ignore
- index += 2;
- } else if (checks[index].equals("nullAllowed")) {
- // ignore
- index += 1;
} else {
- System.out.println("Error: unknown keyword \"" + checks[index] + "\"");
- System.exit(0);
+ index = skipOneCheck(checks, index);
}
}
}
@@ -412,6 +426,69 @@
}
}
+ void emitSentinelCheck(CFunc cfunc, String cname, PrintStream out,
+ boolean isBuffer, boolean emitExceptionCheck, String offset, String remaining, String iii) {
+
+ String[] checks = mChecker.getChecks(cfunc.getName());
+
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("sentinel")) {
+ if (cname != null && !cname.equals(checks[index + 1])) {
+ index += 3;
+ continue;
+ }
+
+ out.println(iii + cname + "_sentinel = false;");
+ out.println(iii + "for (int i = " + remaining +
+ " - 1; i >= 0; i--) {");
+ out.println(iii + indent + "if (" + cname +
+ "[i] == " + checks[index + 2] + "){");
+ out.println(iii + indent + indent +
+ cname + "_sentinel = true;");
+ out.println(iii + indent + indent + "break;");
+ out.println(iii + indent + "}");
+ out.println(iii + "}");
+ out.println(iii +
+ "if (" + cname + "_sentinel == false) {");
+ out.println(iii + indent + "_exception = 1;");
+ out.println(iii + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(iii + indent + "_exceptionMessage = \"" + cname +
+ " must contain " + checks[index + 2] + "!\";");
+ out.println(iii + indent + "goto exit;");
+ out.println(iii + "}");
+
+ needsExit = true;
+ index += 3;
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ }
+
+ void emitLocalVariablesForSentinel(CFunc cfunc, PrintStream out) {
+
+ String[] checks = mChecker.getChecks(cfunc.getName());
+
+ int index = 1;
+ if (checks != null) {
+ while (index < checks.length) {
+ if (checks[index].startsWith("sentinel")) {
+ String cname = checks[index + 1];
+ out.println(indent + "bool " + cname + "_sentinel = false;");
+
+ index += 3;
+
+ } else {
+ index = skipOneCheck(checks, index);
+ }
+ }
+ }
+ }
+
boolean hasNonConstArg(JFunc jfunc, CFunc cfunc, List<Integer> nonPrimitiveArgs) {
if (nonPrimitiveArgs.size() > 0) {
for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
@@ -638,7 +715,7 @@
return "j" + baseType;
}
} else if (jType.isArray()) {
- return "j" + baseType + "Array";
+ return jType.isClass() ? "jobjectArray" : "j" + baseType + "Array";
} else {
return "jobject";
}
@@ -698,8 +775,10 @@
// Append signature to function name
String sig = getJniMangledName(signature).replace('.', '_').replace('/', '_');
- out.print("__" + sig);
- outName += "__" + sig;
+ if (!mUseSimpleMethodNames) {
+ out.print("__" + sig);
+ outName += "__" + sig;
+ }
signature = signature.replace('.', '/');
rsignature = rsignature.replace('.', '/');
@@ -734,11 +813,11 @@
for (int i = 0; i < numArgs; i++) {
out.print(", ");
JType argType = jfunc.getArgType(i);
- String suffix;
+ String suffix = "";
if (!argType.isPrimitive()) {
if (argType.isArray()) {
suffix = "_ref";
- } else {
+ } else if (argType.isBuffer()) {
suffix = "_buf";
}
nonPrimitiveArgs.add(new Integer(i));
@@ -748,9 +827,8 @@
bufferArgNames.add(cname);
numBufferArgs++;
}
- } else {
- suffix = "";
}
+
if (argType.isString()) {
stringArgs.add(new Integer(i));
}
@@ -801,7 +879,14 @@
" \"" + cfunc.getName() + "\");");
if (!isVoid) {
String retval = getErrorReturnValue(cfunc);
- out.println(indent + "return " + retval + ";");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, " + retval + ");");
+ } else {
+ out.println(indent + "return " + retval + ";");
+ }
}
out.println("}");
out.println();
@@ -820,7 +905,14 @@
out.println(indent + indent + " return;");
} else {
String retval = getErrorReturnValue(cfunc);
- out.println(indent + indent + " return " + retval + ";");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, " + retval + ");");
+ } else {
+ out.println(indent + "return " + retval + ";");
+ }
}
out.println(indent + "}");
}
@@ -830,14 +922,18 @@
}
boolean initializeReturnValue = stringArgs.size() > 0;
-
- boolean emitExceptionCheck = (numArrays > 0 || numBuffers > 0 || numStrings > 0) &&
- hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs);
+ boolean emitExceptionCheck = ((numArrays > 0 || numStrings > 0)
+ && (hasNonConstArg(jfunc, cfunc, nonPrimitiveArgs)
+ || (cfunc.hasPointerArg() && numArrays > 0))
+ || hasCheckTest(cfunc)
+ || hasIfTest(cfunc))
+ || (stringArgs.size() > 0);
// mChecker.getChecks(cfunc.getName()) != null
-
// Emit an _exeption variable if there will be error checks
if (emitExceptionCheck) {
out.println(indent + "jint _exception = 0;");
+ out.println(indent + "const char * _exceptionType;");
+ out.println(indent + "const char * _exceptionMessage;");
}
// Emit a single _array or multiple _XXXArray variables
@@ -856,13 +952,49 @@
" _returnValue = " + retval + ";");
} else if (initializeReturnValue) {
out.println(indent + returnType.getDeclaration() +
- " _returnValue = 0;");
+ " _returnValue = 0;");
} else {
out.println(indent + returnType.getDeclaration() +
" _returnValue;");
}
}
+ // Emit local variable declarations for EGL Handles
+ //
+ // Example:
+ //
+ // EGLSurface surface_native = (EGLHandle)fromEGLHandle(_env, surfaceClass, surfaceConstructor, surface);
+ //
+ if (nonPrimitiveArgs.size() > 0) {
+ for (int i = 0; i < nonPrimitiveArgs.size(); i++) {
+ int idx = nonPrimitiveArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String cname = cfunc.getArgName(cIndex);
+
+ if (jfunc.getArgType(idx).isBuffer()
+ || jfunc.getArgType(idx).isArray()
+ || !jfunc.getArgType(idx).isEGLHandle())
+ continue;
+
+ CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
+ String decl = type.getDeclaration();
+ out.println(indent +
+ decl + " " + cname + "_native = (" +
+ decl + ") fromEGLHandle(_env, " +
+ type.getBaseType().toLowerCase() +
+ "GetHandleID, " + jfunc.getArgName(idx) +
+ ");");
+ }
+ }
+
+ // Emit local variable declarations for element/sentinel checks
+ //
+ // Example:
+ //
+ // bool attrib_list_sentinel_found = false;
+ //
+ emitLocalVariablesForSentinel(cfunc, out);
+
// Emit local variable declarations for pointer arguments
//
// Example:
@@ -878,9 +1010,12 @@
int cIndex = jfunc.getArgCIndex(idx);
String cname = cfunc.getArgName(cIndex);
+ if (!jfunc.getArgType(idx).isBuffer() && !jfunc.getArgType(idx).isArray())
+ continue;
+
CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
String decl = type.getDeclaration();
- if (jfunc.getArgType(idx).isArray()) {
+ if (jfunc.getArgType(idx).isArray() && !jfunc.getArgType(idx).isClass()) {
out.println(indent +
decl +
(decl.endsWith("*") ? "" : " ") +
@@ -892,10 +1027,10 @@
out.println(indent +
"jint " + remaining + ";");
out.println(indent +
- decl +
- (decl.endsWith("*") ? "" : " ") +
- jfunc.getArgName(idx) +
- " = (" + decl + ") 0;");
+ decl +
+ (decl.endsWith("*") ? "" : " ") +
+ jfunc.getArgName(idx) +
+ " = (" + decl + ") 0;");
}
out.println();
@@ -923,11 +1058,13 @@
CType type = cfunc.getArgType(jfunc.getArgCIndex(idx));
String decl = type.getDeclaration();
- out.println(indent + "if (!" + cname + ") {");
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", \"" + cname + " == null\");");
- out.println(indent + " goto exit;");
needsExit = true;
+ out.println(indent + "if (!" + cname + ") {");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + cname + " == null\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
out.println(indent + "_native" + cname + " = _env->GetStringUTFChars(" + cname + ", 0);");
@@ -936,7 +1073,7 @@
out.println();
}
- // Emit 'GetPrimitiveArrayCritical' for arrays
+ // Emit 'GetPrimitiveArrayCritical' for non-object arrays
// Emit 'GetPointer' calls for Buffer pointers
int bufArgIdx = 0;
if (nonPrimitiveArgs.size() > 0) {
@@ -950,29 +1087,24 @@
remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
"_" + cname + "Remaining";
- if (jfunc.getArgType(idx).isArray()) {
- out.println(indent +
- "if (!" +
- cname +
- "_ref) {");
- if (emitExceptionCheck) {
- out.println(indent + indent + "_exception = 1;");
- }
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", " +
- "\"" + cname + " == null\");");
- out.println(indent + " goto exit;");
+ if (jfunc.getArgType(idx).isArray()
+ && !jfunc.getArgType(idx).isEGLHandle()) {
needsExit = true;
+ out.println(indent + "if (!" + cname + "_ref) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + cname +" == null\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
-
out.println(indent + "if (" + offset + " < 0) {");
- if (emitExceptionCheck) {
- out.println(indent + indent + "_exception = 1;");
- }
- out.println(indent + " jniThrowException(_env, " +
- "\"java/lang/IllegalArgumentException\", \"" + offset + " < 0\");");
- out.println(indent + " goto exit;");
- needsExit = true;
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent +
+ "_exceptionMessage = \"" + offset +" < 0\";");
+ out.println(indent + indent + "goto exit;");
out.println(indent + "}");
out.println(indent + remaining + " = " +
@@ -997,10 +1129,44 @@
jfunc.getArgName(idx) +
"_ref, (jboolean *)0);");
out.println(indent +
- cname + " = " + cname + "_base + " + offset +
- ";");
+ cname + " = " + cname + "_base + " + offset + ";");
+
+ emitSentinelCheck(cfunc, cname, out, false,
+ emitExceptionCheck, offset,
+ remaining, indent);
out.println();
- } else {
+ } else if (jfunc.getArgType(idx).isArray()
+ && jfunc.getArgType(idx).isEGLHandle()) {
+ needsExit = true;
+ out.println(indent + "if (!" + cname + "_ref) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent + "_exceptionMessage = \"" + cname +" == null\";");
+ out.println(indent + indent + "goto exit;");
+ out.println(indent + "}");
+ out.println(indent + "if (" + offset + " < 0) {");
+ out.println(indent + indent + "_exception = 1;");
+ out.println(indent + indent +
+ "_exceptionType = \"java/lang/IllegalArgumentException\";");
+ out.println(indent + indent + "_exceptionMessage = \"" + offset +" < 0\";");
+ out.println(indent + indent + "goto exit;");
+ out.println(indent + "}");
+
+ out.println(indent + remaining + " = " +
+ (mUseCPlusPlus ? "_env" : "(*_env)") +
+ "->GetArrayLength(" +
+ (mUseCPlusPlus ? "" : "_env, ") +
+ cname + "_ref) - " + offset + ";");
+ emitNativeBoundsChecks(cfunc, cname, out, false,
+ emitExceptionCheck,
+ offset, remaining, " ");
+ out.println(indent +
+ jfunc.getArgName(idx) + " = new " +
+ cfunc.getArgType(cIndex).getBaseType() +
+ "["+ remaining + "];");
+ out.println();
+ } else if (jfunc.getArgType(idx).isBuffer()) {
String array = numBufferArgs <= 1 ? "_array" :
"_" + bufferArgNames.get(bufArgIdx++) + "Array";
@@ -1019,7 +1185,7 @@
cname + "_buf);");
String iii = " ";
out.println(iii + indent + "if ( ! " + cname + " ) {");
- out.println(iii + iii + indent + "return;");
+ out.println(iii + indent + indent + "return;");
out.println(iii + indent + "}");
} else {
out.println(indent +
@@ -1075,18 +1241,23 @@
for (int i = 0; i < numArgs; i++) {
String typecast;
if (i == numArgs - 1 && isVBOPointerFunc) {
- typecast = "const GLvoid *";
+ typecast = "(const GLvoid *)";
} else {
- typecast = cfunc.getArgType(i).getDeclaration();
+ typecast = "(" + cfunc.getArgType(i).getDeclaration() + ")";
}
out.print(indent + indent +
- "(" +
- typecast +
- ")");
+ typecast);
+
if (cfunc.getArgType(i).isConstCharPointer()) {
out.print("_native");
}
- out.print(cfunc.getArgName(i));
+
+ if (cfunc.getArgType(i).isEGLHandle() &&
+ !cfunc.getArgType(i).isPointer()){
+ out.print(cfunc.getArgName(i)+"_native");
+ } else {
+ out.print(cfunc.getArgName(i));
+ }
if (i == numArgs - 1) {
if (isPointerFunc) {
@@ -1114,7 +1285,7 @@
int idx = nonPrimitiveArgs.get(i).intValue();
int cIndex = jfunc.getArgCIndex(idx);
- if (jfunc.getArgType(idx).isArray()) {
+ if (jfunc.getArgType(idx).isArray() && !jfunc.getArgType(idx).isClass()) {
// If the argument is 'const', GL will not write to it.
// In this case, we can use the 'JNI_ABORT' flag to avoid
@@ -1130,8 +1301,7 @@
"_base,");
out.println(indent + indent + indent +
(cfunc.getArgType(cIndex).isConst() ?
- "JNI_ABORT" :
- "_exception ? JNI_ABORT: 0") +
+ "JNI_ABORT" : "_exception ? JNI_ABORT: 0" ) +
");");
out.println(indent + "}");
} else if (jfunc.getArgType(idx).isBuffer()) {
@@ -1144,8 +1314,8 @@
cfunc.getArgName(cIndex) +
", " +
(cfunc.getArgType(cIndex).isConst() ?
- "JNI_FALSE" : "_exception ? JNI_FALSE :" +
- " JNI_TRUE") +
+ "JNI_FALSE" : (emitExceptionCheck ?
+ "_exception ? JNI_FALSE : JNI_TRUE" : "JNI_TRUE")) +
");");
out.println(indent + "}");
}
@@ -1168,9 +1338,60 @@
out.println();
}
+ // Copy results back to java arrays
+ if (nonPrimitiveArgs.size() > 0) {
+ for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) {
+ int idx = nonPrimitiveArgs.get(i).intValue();
+ int cIndex = jfunc.getArgCIndex(idx);
+ String baseType = cfunc.getArgType(cIndex).getBaseType().toLowerCase();
+ if (jfunc.getArgType(idx).isArray() && jfunc.getArgType(idx).isClass()) {
+ remaining = ((numArrays + numBuffers) <= 1) ? "_remaining" :
+ "_" + cfunc.getArgName(cIndex) + "Remaining";
+ offset = numArrays <= 1 ? "offset" : cfunc.getArgName(cIndex) + "Offset";
+ out.println(indent +
+ "if (" + jfunc.getArgName(idx) + ") {");
+ out.println(indent + indent +
+ "for (int i = 0; i < " + remaining + "; i++) {");
+ out.println(indent + indent + indent +
+ "jobject " + cfunc.getArgName(cIndex) +
+ "_new = toEGLHandle(_env, " + baseType +
+ "Class, " + baseType + "Constructor, " +
+ cfunc.getArgName(cIndex) + "[i]);");
+ out.println(indent + indent + indent +
+ (mUseCPlusPlus ? "_env" : "(*_env)") +
+ "->SetObjectArrayElement(" +
+ (mUseCPlusPlus ? "" : "_env, ") +
+ cfunc.getArgName(cIndex) +
+ "_ref, i + " + offset + ", " +
+ cfunc.getArgName(cIndex) + "_new);");
+ out.println(indent + indent + "}");
+ out.println(indent + indent +
+ "delete[] " + jfunc.getArgName(idx) + ";");
+ out.println(indent + "}");
+ }
+ }
+ }
+
+
+ // Throw exception if there is one
+ if (emitExceptionCheck) {
+ out.println(indent + "if (_exception) {");
+ out.println(indent + indent +
+ "jniThrowException(_env, _exceptionType, _exceptionMessage);");
+ out.println(indent + "}");
+
+ }
+
if (!isVoid) {
- out.println(indent + "return _returnValue;");
+ if (cfunc.getType().isEGLHandle()) {
+ String baseType = cfunc.getType().getBaseType().toLowerCase();
+ out.println(indent +
+ "return toEGLHandle(_env, " + baseType + "Class, " +
+ baseType + "Constructor, _returnValue);");
+ } else {
+ out.println(indent + "return _returnValue;");
+ }
}
out.println("}");
diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java
new file mode 100644
index 0000000..d9aebfc
--- /dev/null
+++ b/opengl/tools/glgen/static/egl/EGLConfig.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLConfig extends EGLObjectHandle {
+ public EGLConfig(int handle) {
+ super(handle);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLConfig that = (EGLConfig) o;
+ return getHandle() == that.getHandle();
+ }
+
+ @Override
+ public int hashCode() {
+ return getHandle();
+ }
+}
diff --git a/opengl/tools/glgen/static/egl/EGLContext.java b/opengl/tools/glgen/static/egl/EGLContext.java
new file mode 100644
index 0000000..7b194f3
--- /dev/null
+++ b/opengl/tools/glgen/static/egl/EGLContext.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLContext extends EGLObjectHandle {
+ public EGLContext(int handle) {
+ super(handle);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLContext that = (EGLContext) o;
+ return getHandle() == that.getHandle();
+ }
+
+ @Override
+ public int hashCode() {
+ return getHandle();
+ }
+}
diff --git a/opengl/tools/glgen/static/egl/EGLDisplay.java b/opengl/tools/glgen/static/egl/EGLDisplay.java
new file mode 100644
index 0000000..a090cf0
--- /dev/null
+++ b/opengl/tools/glgen/static/egl/EGLDisplay.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLDisplay extends EGLObjectHandle {
+ public EGLDisplay(int handle) {
+ super(handle);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLDisplay that = (EGLDisplay) o;
+ return getHandle() == that.getHandle();
+ }
+
+ @Override
+ public int hashCode() {
+ return getHandle();
+ }
+}
diff --git a/opengl/tools/glgen/static/egl/EGLObjectHandle.java b/opengl/tools/glgen/static/egl/EGLObjectHandle.java
new file mode 100644
index 0000000..01f9bd4
--- /dev/null
+++ b/opengl/tools/glgen/static/egl/EGLObjectHandle.java
@@ -0,0 +1,33 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public abstract class EGLObjectHandle {
+ private final int mHandle;
+
+ public EGLObjectHandle(int handle) {
+ mHandle = handle;
+ }
+
+ public int getHandle() {
+ return mHandle;
+ }
+}
diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java
new file mode 100644
index 0000000..4800a64
--- /dev/null
+++ b/opengl/tools/glgen/static/egl/EGLSurface.java
@@ -0,0 +1,41 @@
+/*
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.opengl;
+
+/**
+ * @hide
+ */
+public class EGLSurface extends EGLObjectHandle {
+ public EGLSurface(int handle) {
+ super(handle);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ EGLSurface that = (EGLSurface) o;
+ return getHandle() == that.getHandle();
+ }
+
+ @Override
+ public int hashCode() {
+ return getHandle();
+ }
+}
diff --git a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
new file mode 100644
index 0000000..9330c99
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if
@@ -0,0 +1,151 @@
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package android.opengl;
+
+import android.graphics.SurfaceTexture;
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+
+
+/**
+* @hide
+*/
+public class EGL14 {
+
+public static final int EGL_DEFAULT_DISPLAY = 0;
+public static EGLContext EGL_NO_CONTEXT = null;
+public static EGLDisplay EGL_NO_DISPLAY = null;
+public static EGLSurface EGL_NO_SURFACE = null;
+
+public static final int EGL_FALSE = 0;
+public static final int EGL_TRUE = 1;
+public static final int EGL_SUCCESS = 0x3000;
+public static final int EGL_NOT_INITIALIZED = 0x3001;
+public static final int EGL_BAD_ACCESS = 0x3002;
+public static final int EGL_BAD_ALLOC = 0x3003;
+public static final int EGL_BAD_ATTRIBUTE = 0x3004;
+public static final int EGL_BAD_CONFIG = 0x3005;
+public static final int EGL_BAD_CONTEXT = 0x3006;
+public static final int EGL_BAD_CURRENT_SURFACE = 0x3007;
+public static final int EGL_BAD_DISPLAY = 0x3008;
+public static final int EGL_BAD_MATCH = 0x3009;
+public static final int EGL_BAD_NATIVE_PIXMAP = 0x300A;
+public static final int EGL_BAD_NATIVE_WINDOW = 0x300B;
+public static final int EGL_BAD_PARAMETER = 0x300C;
+public static final int EGL_BAD_SURFACE = 0x300D;
+public static final int EGL_CONTEXT_LOST = 0x300E;
+public static final int EGL_BUFFER_SIZE = 0x3020;
+public static final int EGL_ALPHA_SIZE = 0x3021;
+public static final int EGL_BLUE_SIZE = 0x3022;
+public static final int EGL_GREEN_SIZE = 0x3023;
+public static final int EGL_RED_SIZE = 0x3024;
+public static final int EGL_DEPTH_SIZE = 0x3025;
+public static final int EGL_STENCIL_SIZE = 0x3026;
+public static final int EGL_CONFIG_CAVEAT = 0x3027;
+public static final int EGL_CONFIG_ID = 0x3028;
+public static final int EGL_LEVEL = 0x3029;
+public static final int EGL_MAX_PBUFFER_HEIGHT = 0x302A;
+public static final int EGL_MAX_PBUFFER_PIXELS = 0x302B;
+public static final int EGL_MAX_PBUFFER_WIDTH = 0x302C;
+public static final int EGL_NATIVE_RENDERABLE = 0x302D;
+public static final int EGL_NATIVE_VISUAL_ID = 0x302E;
+public static final int EGL_NATIVE_VISUAL_TYPE = 0x302F;
+public static final int EGL_SAMPLES = 0x3031;
+public static final int EGL_SAMPLE_BUFFERS = 0x3032;
+public static final int EGL_SURFACE_TYPE = 0x3033;
+public static final int EGL_TRANSPARENT_TYPE = 0x3034;
+public static final int EGL_TRANSPARENT_BLUE_VALUE = 0x3035;
+public static final int EGL_TRANSPARENT_GREEN_VALUE = 0x3036;
+public static final int EGL_TRANSPARENT_RED_VALUE = 0x3037;
+public static final int EGL_NONE = 0x3038;
+public static final int EGL_BIND_TO_TEXTURE_RGB = 0x3039;
+public static final int EGL_BIND_TO_TEXTURE_RGBA = 0x303A;
+public static final int EGL_MIN_SWAP_INTERVAL = 0x303B;
+public static final int EGL_MAX_SWAP_INTERVAL = 0x303C;
+public static final int EGL_LUMINANCE_SIZE = 0x303D;
+public static final int EGL_ALPHA_MASK_SIZE = 0x303E;
+public static final int EGL_COLOR_BUFFER_TYPE = 0x303F;
+public static final int EGL_RENDERABLE_TYPE = 0x3040;
+public static final int EGL_MATCH_NATIVE_PIXMAP = 0x3041;
+public static final int EGL_CONFORMANT = 0x3042;
+public static final int EGL_SLOW_CONFIG = 0x3050;
+public static final int EGL_NON_CONFORMANT_CONFIG = 0x3051;
+public static final int EGL_TRANSPARENT_RGB = 0x3052;
+public static final int EGL_RGB_BUFFER = 0x308E;
+public static final int EGL_LUMINANCE_BUFFER = 0x308F;
+public static final int EGL_NO_TEXTURE = 0x305C;
+public static final int EGL_TEXTURE_RGB = 0x305D;
+public static final int EGL_TEXTURE_RGBA = 0x305E;
+public static final int EGL_TEXTURE_2D = 0x305F;
+public static final int EGL_PBUFFER_BIT = 0x0001;
+public static final int EGL_PIXMAP_BIT = 0x0002;
+public static final int EGL_WINDOW_BIT = 0x0004;
+public static final int EGL_VG_COLORSPACE_LINEAR_BIT = 0x0020;
+public static final int EGL_VG_ALPHA_FORMAT_PRE_BIT = 0x0040;
+public static final int EGL_MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200;
+public static final int EGL_SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400;
+public static final int EGL_OPENGL_ES_BIT = 0x0001;
+public static final int EGL_OPENVG_BIT = 0x0002;
+public static final int EGL_OPENGL_ES2_BIT = 0x0004;
+public static final int EGL_OPENGL_BIT = 0x0008;
+public static final int EGL_VENDOR = 0x3053;
+public static final int EGL_VERSION = 0x3054;
+public static final int EGL_EXTENSIONS = 0x3055;
+public static final int EGL_CLIENT_APIS = 0x308D;
+public static final int EGL_HEIGHT = 0x3056;
+public static final int EGL_WIDTH = 0x3057;
+public static final int EGL_LARGEST_PBUFFER = 0x3058;
+public static final int EGL_TEXTURE_FORMAT = 0x3080;
+public static final int EGL_TEXTURE_TARGET = 0x3081;
+public static final int EGL_MIPMAP_TEXTURE = 0x3082;
+public static final int EGL_MIPMAP_LEVEL = 0x3083;
+public static final int EGL_RENDER_BUFFER = 0x3086;
+public static final int EGL_VG_COLORSPACE = 0x3087;
+public static final int EGL_VG_ALPHA_FORMAT = 0x3088;
+public static final int EGL_HORIZONTAL_RESOLUTION = 0x3090;
+public static final int EGL_VERTICAL_RESOLUTION = 0x3091;
+public static final int EGL_PIXEL_ASPECT_RATIO = 0x3092;
+public static final int EGL_SWAP_BEHAVIOR = 0x3093;
+public static final int EGL_MULTISAMPLE_RESOLVE = 0x3099;
+public static final int EGL_BACK_BUFFER = 0x3084;
+public static final int EGL_SINGLE_BUFFER = 0x3085;
+public static final int EGL_VG_COLORSPACE_sRGB = 0x3089;
+public static final int EGL_VG_COLORSPACE_LINEAR = 0x308A;
+public static final int EGL_VG_ALPHA_FORMAT_NONPRE = 0x308B;
+public static final int EGL_VG_ALPHA_FORMAT_PRE = 0x308C;
+public static final int EGL_DISPLAY_SCALING = 10000;
+public static final int EGL_BUFFER_PRESERVED = 0x3094;
+public static final int EGL_BUFFER_DESTROYED = 0x3095;
+public static final int EGL_OPENVG_IMAGE = 0x3096;
+public static final int EGL_CONTEXT_CLIENT_TYPE = 0x3097;
+public static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+public static final int EGL_MULTISAMPLE_RESOLVE_DEFAULT = 0x309A;
+public static final int EGL_MULTISAMPLE_RESOLVE_BOX = 0x309B;
+public static final int EGL_OPENGL_ES_API = 0x30A0;
+public static final int EGL_OPENVG_API = 0x30A1;
+public static final int EGL_OPENGL_API = 0x30A2;
+public static final int EGL_DRAW = 0x3059;
+public static final int EGL_READ = 0x305A;
+public static final int EGL_CORE_NATIVE_ENGINE = 0x305B;
+
+ native private static void _nativeClassInit();
+ static {
+ _nativeClassInit();
+ }
diff --git a/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp
new file mode 100644
index 0000000..7904ac7
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/EGL14cHeader.cpp
@@ -0,0 +1,132 @@
+**
+** Copyright 2012, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+#include "jni.h"
+#include "JNIHelp.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
+#include <utils/misc.h>
+
+#include <assert.h>
+#include <EGL/egl.h>
+
+#include <gui/Surface.h>
+#include <gui/SurfaceTexture.h>
+#include <gui/SurfaceTextureClient.h>
+
+#include <ui/ANativeObjectBase.h>
+
+static int initialized = 0;
+
+static jclass egldisplayClass;
+static jclass eglcontextClass;
+static jclass eglsurfaceClass;
+static jclass eglconfigClass;
+
+static jmethodID egldisplayGetHandleID;
+static jmethodID eglcontextGetHandleID;
+static jmethodID eglsurfaceGetHandleID;
+static jmethodID eglconfigGetHandleID;
+
+static jmethodID egldisplayConstructor;
+static jmethodID eglcontextConstructor;
+static jmethodID eglsurfaceConstructor;
+static jmethodID eglconfigConstructor;
+
+static jobject eglNoContextObject;
+static jobject eglNoDisplayObject;
+static jobject eglNoSurfaceObject;
+
+
+
+/* Cache method IDs each time the class is loaded. */
+
+static void
+nativeClassInit(JNIEnv *_env, jclass glImplClass)
+{
+ jclass egldisplayClassLocal = _env->FindClass("android/opengl/EGLDisplay");
+ egldisplayClass = (jclass) _env->NewGlobalRef(egldisplayClassLocal);
+ jclass eglcontextClassLocal = _env->FindClass("android/opengl/EGLContext");
+ eglcontextClass = (jclass) _env->NewGlobalRef(eglcontextClassLocal);
+ jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface");
+ eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal);
+ jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
+ eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
+
+ egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getHandle", "()I");
+ eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getHandle", "()I");
+ eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getHandle", "()I");
+ eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getHandle", "()I");
+
+
+ egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(I)V");
+ eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(I)V");
+ eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(I)V");
+ eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(I)V");
+
+ jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, (jint)EGL_NO_CONTEXT);
+ eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
+ jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, (jint)EGL_NO_DISPLAY);
+ eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
+ jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, (jint)EGL_NO_SURFACE);
+ eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
+
+
+ jclass eglClass = _env->FindClass("android/opengl/EGL14");
+ jfieldID noContextFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_CONTEXT", "Landroid/opengl/EGLContext;");
+ _env->SetStaticObjectField(eglClass, noContextFieldID, eglNoContextObject);
+
+ jfieldID noDisplayFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_DISPLAY", "Landroid/opengl/EGLDisplay;");
+ _env->SetStaticObjectField(eglClass, noDisplayFieldID, eglNoDisplayObject);
+
+ jfieldID noSurfaceFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_SURFACE", "Landroid/opengl/EGLSurface;");
+ _env->SetStaticObjectField(eglClass, noSurfaceFieldID, eglNoSurfaceObject);
+}
+
+static void *
+fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) {
+ if (obj == NULL){
+ jniThrowException(_env, "java/lang/IllegalArgumentException",
+ "Object is set to null.");
+ }
+
+ return (void*) (_env->CallIntMethod(obj, mid));
+}
+
+static jobject
+toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void * handle) {
+ if (cls == eglcontextClass &&
+ (EGLContext)handle == EGL_NO_CONTEXT) {
+ return eglNoContextObject;
+ }
+
+ if (cls == egldisplayClass &&
+ (EGLDisplay)handle == EGL_NO_DISPLAY) {
+ return eglNoDisplayObject;
+ }
+
+ if (cls == eglsurfaceClass &&
+ (EGLSurface)handle == EGL_NO_SURFACE) {
+ return eglNoSurfaceObject;
+ }
+
+ return _env->NewObject(cls, con, (jint)handle);
+}
+
+// --------------------------------------------------------------------------
diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
new file mode 100644
index 0000000..610cde5
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
@@ -0,0 +1,154 @@
+/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
+static jobject
+android_eglCreateWindowSurface
+ (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) {
+ jint _exception = 0;
+ const char * _exceptionType = "";
+ const char * _exceptionMessage = "";
+ EGLSurface _returnValue = (EGLSurface) 0;
+ EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+ EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+ int attrib_list_sentinel = 0;
+ EGLint *attrib_list_base = (EGLint *) 0;
+ jint _remaining;
+ EGLint *attrib_list = (EGLint *) 0;
+ android::sp<ANativeWindow> window;
+
+ if (!attrib_list_ref) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "attrib_list == null";
+ goto exit;
+ }
+ if (offset < 0) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "offset < 0";
+ goto exit;
+ }
+ if (win == NULL) {
+not_valid_surface:
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
+ goto exit;
+ }
+
+ window = android::android_Surface_getNativeWindow(_env, win);
+
+ if (window == NULL)
+ goto not_valid_surface;
+
+ _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+ attrib_list_base = (EGLint *)
+ _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ attrib_list = attrib_list_base + offset;
+ attrib_list_sentinel = 0;
+ for (int i = _remaining - 1; i >= 0; i--) {
+ if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
+ attrib_list_sentinel = 1;
+ break;
+ }
+ }
+ if (attrib_list_sentinel == 0) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "attrib_list must contain EGL_NONE!";
+ goto exit;
+ }
+
+ _returnValue = eglCreateWindowSurface(
+ (EGLDisplay)dpy_native,
+ (EGLConfig)config_native,
+ (EGLNativeWindowType)window.get(),
+ (EGLint *)attrib_list
+ );
+
+exit:
+ if (attrib_list_base) {
+ _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ JNI_ABORT);
+ }
+ if (_exception) {
+ jniThrowException(_env, _exceptionType, _exceptionMessage);
+ }
+ return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list ) */
+static jobject
+android_eglCreateWindowSurfaceTexture
+ (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject win, jintArray attrib_list_ref, jint offset) {
+ jint _exception = 0;
+ const char * _exceptionType = "";
+ const char * _exceptionMessage = "";
+ EGLSurface _returnValue = (EGLSurface) 0;
+ EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+ EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+ int attrib_list_sentinel = 0;
+ EGLint *attrib_list_base = (EGLint *) 0;
+ jint _remaining;
+ EGLint *attrib_list = (EGLint *) 0;
+ android::sp<ANativeWindow> window;
+ android::sp<android::SurfaceTexture> surfaceTexture;
+
+ if (!attrib_list_ref) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "attrib_list == null";
+ goto exit;
+ }
+ if (offset < 0) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "offset < 0";
+ goto exit;
+ }
+ if (win == NULL) {
+not_valid_surface:
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "Make sure the SurfaceView or associated SurfaceHolder has a valid Surface";
+ goto exit;
+ }
+ surfaceTexture = android::SurfaceTexture_getSurfaceTexture(_env, win);
+ window = new android::SurfaceTextureClient(surfaceTexture);
+
+ if (window == NULL)
+ goto not_valid_surface;
+
+ _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+ attrib_list_base = (EGLint *)
+ _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
+ attrib_list = attrib_list_base + offset;
+ attrib_list_sentinel = 0;
+ for (int i = _remaining - 1; i >= 0; i--) {
+ if (*((EGLint*)(attrib_list + i)) == EGL_NONE){
+ attrib_list_sentinel = 1;
+ break;
+ }
+ }
+ if (attrib_list_sentinel == 0) {
+ _exception = 1;
+ _exceptionType = "java/lang/IllegalArgumentException";
+ _exceptionMessage = "attrib_list must contain EGL_NONE!";
+ goto exit;
+ }
+
+ _returnValue = eglCreateWindowSurface(
+ (EGLDisplay)dpy_native,
+ (EGLConfig)config_native,
+ (EGLNativeWindowType)window.get(),
+ (EGLint *)attrib_list
+ );
+
+exit:
+ if (attrib_list_base) {
+ _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
+ JNI_ABORT);
+ }
+ if (_exception) {
+ jniThrowException(_env, _exceptionType, _exceptionMessage);
+ }
+ return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java
new file mode 100644
index 0000000..e42334e
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.java
@@ -0,0 +1,48 @@
+ // C function EGLSurface eglCreateWindowSurface ( EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list )
+
+ private static native EGLSurface _eglCreateWindowSurface(
+ EGLDisplay dpy,
+ EGLConfig config,
+ Object win,
+ int[] attrib_list,
+ int offset
+ );
+
+ private static native EGLSurface _eglCreateWindowSurfaceTexture(
+ EGLDisplay dpy,
+ EGLConfig config,
+ Object win,
+ int[] attrib_list,
+ int offset
+ );
+
+ public static EGLSurface eglCreateWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ Object win,
+ int[] attrib_list,
+ int offset
+ ){
+ Surface sur = null;
+ if (win instanceof SurfaceView) {
+ SurfaceView surfaceView = (SurfaceView)win;
+ sur = surfaceView.getHolder().getSurface();
+ } else if (win instanceof SurfaceHolder) {
+ SurfaceHolder holder = (SurfaceHolder)win;
+ sur = holder.getSurface();
+ }
+
+ EGLSurface surface;
+ if (sur != null) {
+ surface = _eglCreateWindowSurface(dpy, config, sur, attrib_list, offset);
+ } else if (win instanceof SurfaceTexture) {
+ surface = _eglCreateWindowSurfaceTexture(dpy, config,
+ win, attrib_list, offset);
+ } else {
+ throw new java.lang.UnsupportedOperationException(
+ "eglCreateWindowSurface() can only be called with an instance of " +
+ "SurfaceView, SurfaceTexture or SurfaceHolder at the moment, " +
+ "this will be fixed later.");
+ }
+
+ return surface;
+ }
diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg
new file mode 100644
index 0000000..c37d05b
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.nativeReg
@@ -0,0 +1,2 @@
+{"_eglCreateWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurface },
+{"_eglCreateWindowSurfaceTexture", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/lang/Object;[II)Landroid/opengl/EGLSurface;", (void *) android_eglCreateWindowSurfaceTexture },
diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.cpp b/opengl/tools/glgen/stubs/egl/eglQueryString.cpp
new file mode 100644
index 0000000..625dad7
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglQueryString.cpp
@@ -0,0 +1,10 @@
+/* const char * eglQueryString ( EGLDisplay dpy, EGLint name ) */
+static jstring
+android_eglQueryString__Landroind_opengl_EGLDisplay_2I
+ (JNIEnv *_env, jobject _this, jobject dpy, jint name) {
+ const char* chars = (const char*) eglQueryString(
+ (EGLDisplay)fromEGLHandle(_env, egldisplayGetHandleID, dpy),
+ (EGLint)name
+ );
+ return _env->NewStringUTF(chars);
+}
diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.java b/opengl/tools/glgen/stubs/egl/eglQueryString.java
new file mode 100644
index 0000000..f5d5a38
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglQueryString.java
@@ -0,0 +1,6 @@
+ // C function const char * eglQueryString ( EGLDisplay dpy, EGLint name )
+
+ public static native String eglQueryString(
+ EGLDisplay dpy,
+ int name
+ );
diff --git a/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg b/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg
new file mode 100644
index 0000000..8276cdb
--- /dev/null
+++ b/opengl/tools/glgen/stubs/egl/eglQueryString.nativeReg
@@ -0,0 +1 @@
+{"eglQueryString", "(Landroid/opengl/EGLDisplay;I)Ljava/lang/String;", (void *) android_eglQueryString__Landroind_opengl_EGLDisplay_2I },
diff --git a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
index cd730aa..e3aea76 100644
--- a/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
+++ b/opengl/tools/glgen/stubs/jsr239/GLImplHeader.java-impl
@@ -22,6 +22,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.os.Build;
+import android.os.UserId;
import android.util.Log;
import java.nio.Buffer;
@@ -66,7 +67,7 @@
int version = 0;
IPackageManager pm = AppGlobals.getPackageManager();
try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0);
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(appName, 0, UserId.myUserId());
if (applicationInfo != null) {
version = applicationInfo.targetSdkVersion;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0d1cb45..a09b5c7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -145,14 +145,6 @@
mSurfaceTexture->setName(name);
}
-void Layer::validateVisibility(const Transform& globalTransform, const DisplayHardware& hw) {
- LayerBase::validateVisibility(globalTransform, hw);
-
- // This optimization allows the SurfaceTexture to bake in
- // the rotation so hardware overlays can be used
- mSurfaceTexture->setTransformHint(getTransformHint());
-}
-
sp<ISurface> Layer::createSurface()
{
class BSurface : public BnSurface, public LayerCleaner {
@@ -225,7 +217,8 @@
} else if (mActiveBuffer != NULL){
crop = Rect(mActiveBuffer->getWidth(), mActiveBuffer->getHeight());
} else {
- crop = Rect(mTransformedBounds.width(), mTransformedBounds.height());
+ crop.makeInvalid();
+ return crop;
}
// ... then reduce that in the same proportions as the window crop reduces
@@ -258,9 +251,11 @@
return crop;
}
-void Layer::setGeometry(HWComposer::HWCLayerInterface& layer)
+void Layer::setGeometry(
+ const DisplayHardware& hw,
+ HWComposer::HWCLayerInterface& layer)
{
- LayerBaseClient::setGeometry(layer);
+ LayerBaseClient::setGeometry(hw, layer);
// enable this layer
layer.setSkip(false);
@@ -276,12 +271,11 @@
* 1) buffer orientation/flip/mirror
* 2) state transformation (window manager)
* 3) layer orientation (screen orientation)
- * mTransform is already the composition of (2) and (3)
* (NOTE: the matrices are multiplied in reverse order)
*/
const Transform bufferOrientation(mCurrentTransform);
- const Transform tr(mTransform * bufferOrientation);
+ const Transform tr(hw.getTransform() * s.transform * bufferOrientation);
// this gives us only the "orientation" component of the transform
const uint32_t finalTransform = tr.getOrientation();
@@ -339,7 +333,7 @@
const sp<LayerBase>& layer(drawingLayers[i]);
if (layer.get() == static_cast<LayerBase const*>(this))
break;
- under.orSelf(layer->visibleRegionScreen);
+ under.orSelf( hw.getTransform().transform(layer->visibleRegion) );
}
// if not everything below us is covered, we plug the holes!
Region holes(clip.subtract(under));
@@ -527,10 +521,11 @@
return mQueuedFrames > 0;
}
-void Layer::lockPageFlip(bool& recomputeVisibleRegions)
+Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
ATRACE_CALL();
+ Region outDirtyRegion;
if (mQueuedFrames > 0) {
// if we've already called updateTexImage() without going through
@@ -539,8 +534,7 @@
// compositionComplete() call.
// we'll trigger an update in onPreComposition().
if (mRefreshPending) {
- mPostedDirtyRegion.clear();
- return;
+ return outDirtyRegion;
}
// Capture the old state of the layer for comparisons later
@@ -637,17 +631,21 @@
Reject r(mDrawingState, currentState(), recomputeVisibleRegions);
+ // XXX: not sure if setTransformHint belongs here
+ // it should only be needed when the main screen orientation changes
+ mSurfaceTexture->setTransformHint(getTransformHint());
+
if (mSurfaceTexture->updateTexImage(&r) < NO_ERROR) {
// something happened!
recomputeVisibleRegions = true;
- return;
+ return outDirtyRegion;
}
// update the active buffer
mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
if (mActiveBuffer == NULL) {
// this can only happen if the very first buffer was rejected.
- return;
+ return outDirtyRegion;
}
mRefreshPending = true;
@@ -686,38 +684,17 @@
recomputeVisibleRegions = true;
}
- // FIXME: mPostedDirtyRegion = dirty & bounds
- const Layer::State& front(drawingState());
- mPostedDirtyRegion.set(front.active.w, front.active.h);
-
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterx(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ // FIXME: postedRegion should be dirty & bounds
+ const Layer::State& front(drawingState());
+ Region dirtyRegion(Rect(front.active.w, front.active.h));
+
+ // transform the dirty region to window-manager space
+ outDirtyRegion = (front.transform.transform(dirtyRegion));
}
-}
-
-void Layer::unlockPageFlip(
- const Transform& planeTransform, Region& outDirtyRegion)
-{
- ATRACE_CALL();
-
- Region postedRegion(mPostedDirtyRegion);
- if (!postedRegion.isEmpty()) {
- mPostedDirtyRegion.clear();
- if (!visibleRegionScreen.isEmpty()) {
- // The dirty region is given in the layer's coordinate space
- // transform the dirty region by the surface's transformation
- // and the global transformation.
- const Layer::State& s(drawingState());
- const Transform tr(planeTransform * s.transform);
- postedRegion = tr.transform(postedRegion);
-
- // At this point, the dirty region is in screen space.
- // Make sure it's constrained by the visible region (which
- // is in screen space as well).
- postedRegion.andSelf(visibleRegionScreen);
- outDirtyRegion.orSelf(postedRegion);
- }
- }
+ return outDirtyRegion;
}
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
@@ -786,7 +763,14 @@
uint32_t Layer::getTransformHint() const {
uint32_t orientation = 0;
if (!mFlinger->mDebugDisableTransformHint) {
- orientation = getPlaneOrientation();
+ // The transform hint is used to improve performance on the main
+ // display -- we can only have a single transform hint, it cannot
+ // apply to all displays.
+ // This is why we use the default display here. This is not an
+ // oversight.
+ const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware());
+ const Transform& planeTransform(hw.getTransform());
+ orientation = planeTransform.getOrientation();
if (orientation & Transform::ROT_INVALID) {
orientation = 0;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index b6ae0ae..239250d 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -64,20 +64,20 @@
bool isFixedSize() const;
// LayerBase interface
- virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setGeometry(const DisplayHardware& hw,
+ HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);
+
virtual void onDraw(const DisplayHardware& hw, const Region& clip) const;
virtual uint32_t doTransaction(uint32_t transactionFlags);
- virtual void lockPageFlip(bool& recomputeVisibleRegions);
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+ virtual Region latchBuffer(bool& recomputeVisibleRegions);
virtual bool isOpaque() const;
virtual bool isSecure() const { return mSecure; }
virtual bool isProtected() const;
virtual void onRemoved();
virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
virtual void setName(const String8& name);
- virtual void validateVisibility(const Transform& globalTransform, const DisplayHardware& hw);
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;
@@ -142,7 +142,6 @@
// page-flip thread (currently main thread)
bool mSecure; // no screenshots
bool mProtectedByApp; // application requires protected path to external sink
- Region mPostedDirtyRegion;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 8350d27..2070cb9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -45,8 +45,6 @@
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger), mFiltering(false),
mNeedsFiltering(false),
- mOrientation(0),
- mPlaneOrientation(0),
mTransactionFlags(0),
mPremultipliedAlpha(true), mName("unnamed"), mDebug(false)
{
@@ -170,19 +168,14 @@
return true;
}
-Rect LayerBase::visibleBounds() const
-{
- return mTransformedBounds;
-}
-
void LayerBase::setVisibleRegion(const Region& visibleRegion) {
// always called from main thread
- visibleRegionScreen = visibleRegion;
+ this->visibleRegion = visibleRegion;
}
void LayerBase::setCoveredRegion(const Region& coveredRegion) {
// always called from main thread
- coveredRegionScreen = coveredRegion;
+ this->coveredRegion = coveredRegion;
}
uint32_t LayerBase::doTransaction(uint32_t flags)
@@ -219,57 +212,45 @@
return flags;
}
-void LayerBase::validateVisibility(const Transform& planeTransform, const DisplayHardware& hw)
+void LayerBase::computeGeometry(const DisplayHardware& hw, LayerMesh* mesh) const
{
const Layer::State& s(drawingState());
- const Transform tr(planeTransform * s.transform);
- const bool transformed = tr.transformed();
+ const Transform tr(hw.getTransform() * s.transform);
const uint32_t hw_h = hw.getHeight();
const Rect& crop(s.active.crop);
-
Rect win(s.active.w, s.active.h);
if (!crop.isEmpty()) {
win.intersect(crop, &win);
}
-
- mNumVertices = 4;
- tr.transform(mVertices[0], win.left, win.top);
- tr.transform(mVertices[1], win.left, win.bottom);
- tr.transform(mVertices[2], win.right, win.bottom);
- tr.transform(mVertices[3], win.right, win.top);
- for (size_t i=0 ; i<4 ; i++)
- mVertices[i][1] = hw_h - mVertices[i][1];
-
- if (CC_UNLIKELY(transformed)) {
- // NOTE: here we could also punt if we have too many rectangles
- // in the transparent region
- if (tr.preserveRects()) {
- // transform the transparent region
- transparentRegionScreen = tr.transform(s.transparentRegion);
- } else {
- // transformation too complex, can't do the transparent region
- // optimization.
- transparentRegionScreen.clear();
+ if (mesh) {
+ tr.transform(mesh->mVertices[0], win.left, win.top);
+ tr.transform(mesh->mVertices[1], win.left, win.bottom);
+ tr.transform(mesh->mVertices[2], win.right, win.bottom);
+ tr.transform(mesh->mVertices[3], win.right, win.top);
+ for (size_t i=0 ; i<4 ; i++) {
+ mesh->mVertices[i][1] = hw_h - mesh->mVertices[i][1];
}
- } else {
- transparentRegionScreen = s.transparentRegion;
}
-
- // cache a few things...
- mOrientation = tr.getOrientation();
- mPlaneOrientation = planeTransform.getOrientation();
- mTransform = tr;
- mTransformedBounds = tr.transform(win);
}
-void LayerBase::lockPageFlip(bool& recomputeVisibleRegions) {
+Rect LayerBase::computeBounds() const {
+ const Layer::State& s(drawingState());
+ const Rect& crop(s.active.crop);
+ Rect win(s.active.w, s.active.h);
+ if (!crop.isEmpty()) {
+ win.intersect(crop, &win);
+ }
+ return s.transform.transform(win);
}
-void LayerBase::unlockPageFlip(
- const Transform& planeTransform, Region& outDirtyRegion) {
+Region LayerBase::latchBuffer(bool& recomputeVisibleRegions) {
+ Region result;
+ return result;
}
-void LayerBase::setGeometry(HWComposer::HWCLayerInterface& layer)
+void LayerBase::setGeometry(
+ const DisplayHardware& hw,
+ HWComposer::HWCLayerInterface& layer)
{
layer.setDefaultState();
@@ -289,10 +270,14 @@
HWC_BLENDING_COVERAGE);
}
- // scaling is already applied in mTransformedBounds
- layer.setFrame(mTransformedBounds);
- layer.setVisibleRegionScreen(visibleRegionScreen);
- layer.setCrop(mTransformedBounds.getBounds());
+ const Transform& tr = hw.getTransform();
+ Rect transformedBounds(computeBounds());
+ transformedBounds = tr.transform(transformedBounds);
+
+ // scaling is already applied in transformedBounds
+ layer.setFrame(transformedBounds);
+ layer.setCrop(transformedBounds.getBounds());
+ layer.setVisibleRegionScreen(tr.transform(visibleRegion));
}
void LayerBase::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
@@ -335,8 +320,11 @@
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
- glVertexPointer(2, GL_FLOAT, 0, mVertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
}
void LayerBase::clearWithOpenGL(const DisplayHardware& hw, const Region& clip) const
@@ -371,6 +359,12 @@
}
}
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
+ // TODO: we probably want to generate the texture coords with the mesh
+ // here we assume that we only have 4 vertices
+
struct TexCoords {
GLfloat u;
GLfloat v;
@@ -380,9 +374,9 @@
if (!s.active.crop.isEmpty()) {
crop = s.active.crop;
}
- GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
- GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h);
- GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
+ GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w);
+ GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h);
+ GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w);
GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h);
TexCoords texCoords[4];
@@ -399,9 +393,9 @@
}
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, mVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_BLEND);
@@ -417,8 +411,7 @@
result.append(buffer);
s.transparentRegion.dump(result, "transparentRegion");
- transparentRegionScreen.dump(result, "transparentRegionScreen");
- visibleRegionScreen.dump(result, "visibleRegionScreen");
+ visibleRegion.dump(result, "visibleRegion");
snprintf(buffer, SIZE,
" "
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 83e871c..d227b2d 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -57,9 +57,9 @@
DisplayID dpy;
mutable bool contentDirty;
- Region visibleRegionScreen;
- Region transparentRegionScreen;
- Region coveredRegionScreen;
+ // regions below are in window-manager space
+ Region visibleRegion;
+ Region coveredRegion;
int32_t sequence;
struct Geometry {
@@ -86,6 +86,20 @@
Region transparentRegion;
};
+ class LayerMesh {
+ friend class LayerBase;
+ GLfloat mVertices[4][2];
+ size_t mNumVertices;
+ public:
+ LayerMesh() : mNumVertices(4) { }
+ GLfloat const* getVertices() const {
+ return &mVertices[0][0];
+ }
+ size_t getVertexCount() const {
+ return mNumVertices;
+ }
+ };
+
virtual void setName(const String8& name);
String8 getName() const;
@@ -105,15 +119,18 @@
uint32_t getTransactionFlags(uint32_t flags);
uint32_t setTransactionFlags(uint32_t flags);
-
- Rect visibleBounds() const;
+
+ void computeGeometry(const DisplayHardware& hw, LayerMesh* mesh) const;
+ Rect computeBounds() const;
+
virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
virtual sp<Layer> getLayer() const { return 0; }
virtual const char* getTypeId() const { return "LayerBase"; }
- virtual void setGeometry(HWComposer::HWCLayerInterface& layer);
+ virtual void setGeometry(const DisplayHardware& hw,
+ HWComposer::HWCLayerInterface& layer);
virtual void setPerFrameData(HWComposer::HWCLayerInterface& layer);
virtual void setAcquireFence(HWComposer::HWCLayerInterface& layer);
@@ -156,26 +173,13 @@
virtual void setCoveredRegion(const Region& coveredRegion);
/**
- * validateVisibility - cache a bunch of things
- */
- virtual void validateVisibility(const Transform& globalTransform, const DisplayHardware& hw);
-
- /**
- * lockPageFlip - called each time the screen is redrawn and returns whether
+ * latchBuffer - called each time the screen is redrawn and returns whether
* the visible regions need to be recomputed (this is a fairly heavy
* operation, so this should be set only if needed). Typically this is used
* to figure out if the content or size of a surface has changed.
*/
- virtual void lockPageFlip(bool& recomputeVisibleRegions);
-
- /**
- * unlockPageFlip - called each time the screen is redrawn. updates the
- * final dirty region wrt the planeTransform.
- * At this point, all visible regions, surface position and size, etc... are
- * correct.
- */
- virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-
+ virtual Region latchBuffer(bool& recomputeVisibleRegions);
+
/**
* isOpaque - true if this surface is opaque
*/
@@ -233,9 +237,6 @@
inline const State& currentState() const { return mCurrentState; }
inline State& currentState() { return mCurrentState; }
- int32_t getOrientation() const { return mOrientation; }
- int32_t getPlaneOrientation() const { return mPlaneOrientation; }
-
void clearWithOpenGL(const DisplayHardware& hw, const Region& clip) const;
protected:
@@ -253,19 +254,10 @@
// Whether filtering is forced on or not
bool mFiltering;
- // cached during validateVisibility()
// Whether filtering is needed b/c of the drawingstate
bool mNeedsFiltering;
protected:
- // cached during validateVisibility()
- int32_t mOrientation;
- int32_t mPlaneOrientation;
- Transform mTransform;
- GLfloat mVertices[4][2];
- size_t mNumVertices;
- Rect mTransformedBounds;
-
// these are protected by an external lock
State mCurrentState;
State mDrawingState;
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index ceead45..5c37d01 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -58,8 +58,11 @@
glColor4f(0, 0, 0, alpha);
- glVertexPointer(2, GL_FLOAT, 0, mVertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
glDisable(GL_BLEND);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index d046879..f2bf19d 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -120,6 +120,9 @@
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
+ LayerMesh mesh;
+ computeGeometry(hw, &mesh);
+
glColor4f(0, 0, 0, alpha);
glDisable(GL_TEXTURE_EXTERNAL_OES);
@@ -133,8 +136,8 @@
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, mTexCoords);
- glVertexPointer(2, GL_FLOAT, 0, mVertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices);
+ glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices());
+ glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount());
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index 290fff4..3f77f74 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -49,13 +49,13 @@
// ---------------------------------------------------------------------------
-void MessageQueue::Handler::signalRefresh() {
+void MessageQueue::Handler::dispatchRefresh() {
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
}
}
-void MessageQueue::Handler::signalInvalidate() {
+void MessageQueue::Handler::dispatchInvalidate() {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
@@ -132,13 +132,31 @@
return NO_ERROR;
}
+/* when INVALIDATE_ON_VSYNC is set SF only processes
+ * buffer updates on VSYNC and performs a refresh immediately
+ * after.
+ *
+ * when INVALIDATE_ON_VSYNC is set to false, SF will instead
+ * perform the buffer updates immediately, but the refresh only
+ * at the next VSYNC.
+ * THIS MODE IS BUGGY ON GALAXY NEXUS AND WILL CAUSE HANGS
+ */
+#define INVALIDATE_ON_VSYNC 1
+
void MessageQueue::invalidate() {
-// mHandler->signalInvalidate();
+#if INVALIDATE_ON_VSYNC
mEvents->requestNextVsync();
+#else
+ mHandler->dispatchInvalidate();
+#endif
}
void MessageQueue::refresh() {
+#if INVALIDATE_ON_VSYNC
+ mHandler->dispatchRefresh();
+#else
mEvents->requestNextVsync();
+#endif
}
int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
@@ -152,7 +170,11 @@
while ((n = DisplayEventReceiver::getEvents(mEventTube, buffer, 8)) > 0) {
for (int i=0 ; i<n ; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- mHandler->signalRefresh();
+#if INVALIDATE_ON_VSYNC
+ mHandler->dispatchInvalidate();
+#else
+ mHandler->dispatchRefresh();
+#endif
break;
}
}
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index ea29e7e..710b2c2 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -70,8 +70,8 @@
public:
Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) { }
virtual void handleMessage(const Message& message);
- void signalRefresh();
- void signalInvalidate();
+ void dispatchRefresh();
+ void dispatchInvalidate();
};
friend class Handler;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 3b2bf00..6c900be 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -425,100 +425,117 @@
return res;
}
-bool SurfaceFlinger::threadLoop()
-{
+bool SurfaceFlinger::threadLoop() {
waitForEvent();
return true;
}
-void SurfaceFlinger::onMessageReceived(int32_t what)
-{
+void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
- case MessageQueue::REFRESH: {
-// case MessageQueue::INVALIDATE: {
- // if we're in a global transaction, don't do anything.
- const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
- uint32_t transactionFlags = peekTransactionFlags(mask);
- if (CC_UNLIKELY(transactionFlags)) {
- handleTransaction(transactionFlags);
- }
-
- // post surfaces (if needed)
- handlePageFlip();
-
-// signalRefresh();
-//
-// } break;
-//
-// case MessageQueue::REFRESH: {
-
- handleRefresh();
-
- // TODO: iterate through all displays
- const DisplayHardware& hw(getDisplayHardware(0));
-
-// if (mDirtyRegion.isEmpty()) {
-// return;
-// }
-
- if (CC_UNLIKELY(mHwWorkListDirty)) {
- // build the h/w work list
- handleWorkList(hw);
- }
-
- if (CC_LIKELY(hw.canDraw())) {
- // repaint the framebuffer (if needed)
- handleRepaint(hw);
- // inform the h/w that we're done compositing
- hw.compositionComplete();
- postFramebuffer();
- } else {
- // pretend we did the post
- hw.compositionComplete();
- }
-
- // render to the external display if we have one
- EGLSurface externalDisplaySurface = getExternalDisplaySurface();
- if (externalDisplaySurface != EGL_NO_SURFACE) {
- EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
- EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
- externalDisplaySurface, externalDisplaySurface,
- eglGetCurrentContext());
-
- ALOGE_IF(!success, "eglMakeCurrent -> external failed");
-
- if (success) {
- // redraw the screen entirely...
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glClearColor(0,0,0,1);
- glClear(GL_COLOR_BUFFER_BIT);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
- const size_t count = layers.size();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer(layers[i]);
- layer->drawForSreenShot(hw);
- }
-
- success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
- ALOGE_IF(!success, "external display eglSwapBuffers failed");
-
- hw.compositionComplete();
- }
-
- success = eglMakeCurrent(eglGetCurrentDisplay(),
- cur, cur, eglGetCurrentContext());
-
- ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
- }
-
- } break;
+ case MessageQueue::INVALIDATE:
+ handleMessageTransaction();
+ handleMessageInvalidate();
+ signalRefresh();
+ break;
+ case MessageQueue::REFRESH:
+ handleMessageRefresh();
+ break;
}
}
+void SurfaceFlinger::handleMessageTransaction() {
+ const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+ uint32_t transactionFlags = peekTransactionFlags(mask);
+ if (transactionFlags) {
+ Region dirtyRegion;
+ dirtyRegion = handleTransaction(transactionFlags);
+ // XXX: dirtyRegion should be per screen
+ mDirtyRegion |= dirtyRegion;
+ }
+}
+
+void SurfaceFlinger::handleMessageInvalidate() {
+ Region dirtyRegion;
+ dirtyRegion = handlePageFlip();
+ // XXX: dirtyRegion should be per screen
+ mDirtyRegion |= dirtyRegion;
+}
+
+void SurfaceFlinger::handleMessageRefresh() {
+ handleRefresh();
+
+ // XXX: dirtyRegion should be per screen, we should check all of them
+ if (mDirtyRegion.isEmpty()) {
+ return;
+ }
+
+ // TODO: iterate through all displays
+ const DisplayHardware& hw(getDisplayHardware(0));
+
+ // XXX: dirtyRegion should be per screen
+ // transform the dirty region into this screen's coordinate space
+ const Transform& planeTransform(hw.getTransform());
+ mDirtyRegion = planeTransform.transform(mDirtyRegion);
+ mDirtyRegion.orSelf(getAndClearInvalidateRegion());
+ mDirtyRegion.andSelf(hw.bounds());
+
+
+ if (CC_UNLIKELY(mHwWorkListDirty)) {
+ // build the h/w work list
+ handleWorkList(hw);
+ }
+
+ if (CC_LIKELY(hw.canDraw())) {
+ // repaint the framebuffer (if needed)
+ handleRepaint(hw);
+ // inform the h/w that we're done compositing
+ hw.compositionComplete();
+ postFramebuffer();
+ } else {
+ // pretend we did the post
+ hw.compositionComplete();
+ }
+
+ // render to the external display if we have one
+ EGLSurface externalDisplaySurface = getExternalDisplaySurface();
+ if (externalDisplaySurface != EGL_NO_SURFACE) {
+ EGLSurface cur = eglGetCurrentSurface(EGL_DRAW);
+ EGLBoolean success = eglMakeCurrent(eglGetCurrentDisplay(),
+ externalDisplaySurface, externalDisplaySurface,
+ eglGetCurrentContext());
+
+ ALOGE_IF(!success, "eglMakeCurrent -> external failed");
+
+ if (success) {
+ // redraw the screen entirely...
+ glDisable(GL_TEXTURE_EXTERNAL_OES);
+ glDisable(GL_TEXTURE_2D);
+ glClearColor(0,0,0,1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+ const size_t count = layers.size();
+ for (size_t i=0 ; i<count ; ++i) {
+ const sp<LayerBase>& layer(layers[i]);
+ layer->drawForSreenShot(hw);
+ }
+
+ success = eglSwapBuffers(eglGetCurrentDisplay(), externalDisplaySurface);
+ ALOGE_IF(!success, "external display eglSwapBuffers failed");
+
+ hw.compositionComplete();
+ }
+
+ success = eglMakeCurrent(eglGetCurrentDisplay(),
+ cur, cur, eglGetCurrentContext());
+
+ ALOGE_IF(!success, "eglMakeCurrent -> internal failed");
+ }
+
+}
+
void SurfaceFlinger::postFramebuffer()
{
ATRACE_CALL();
@@ -564,10 +581,12 @@
mSwapRegion.clear();
}
-void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
+Region SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
ATRACE_CALL();
+ Region dirtyRegion;
+
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
@@ -580,16 +599,19 @@
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
transactionFlags = getTransactionFlags(mask);
- handleTransactionLocked(transactionFlags);
+ dirtyRegion = handleTransactionLocked(transactionFlags);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
invalidateHwcGeometry();
// here the transaction has been committed
+
+ return dirtyRegion;
}
-void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
+Region SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
+ Region dirtyRegion;
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();
@@ -652,13 +674,34 @@
const sp<LayerBase>& layer(previousLayers[i]);
if (currentLayers.indexOf( layer ) < 0) {
// this layer is not visible anymore
- mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
+ // TODO: we could traverse the tree from front to back and compute the actual visible region
+ // TODO: we could cache the transformed region
+ Layer::State front(layer->drawingState());
+ Region visibleReg = front.transform.transform(
+ Region(Rect(front.active.w, front.active.h)));
+ dirtyRegion.orSelf(visibleReg);
}
}
}
}
commitTransaction();
+ return dirtyRegion;
+}
+
+void SurfaceFlinger::commitTransaction()
+{
+ if (!mLayersPendingRemoval.isEmpty()) {
+ // Notify removed layers now that they can't be drawn from
+ for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
+ mLayersPendingRemoval[i]->onRemoved();
+ }
+ mLayersPendingRemoval.clear();
+ }
+
+ mDrawingState = mCurrentState;
+ mTransationPending = false;
+ mTransactionCV.broadcast();
}
void SurfaceFlinger::computeVisibleRegions(
@@ -666,10 +709,6 @@
{
ATRACE_CALL();
- const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: we shouldn't rely on DisplayHardware here
- const Transform& planeTransform(hw.getTransform());
- const Region screenRegion(hw.bounds());
-
Region aboveOpaqueLayers;
Region aboveCoveredLayers;
Region dirty;
@@ -679,7 +718,6 @@
size_t i = currentLayers.size();
while (i--) {
const sp<LayerBase>& layer = currentLayers[i];
- layer->validateVisibility(planeTransform, hw);
// start with the whole surface at its current location
const Layer::State& s(layer->drawingState());
@@ -707,17 +745,30 @@
// handle hidden surfaces by setting the visible region to empty
if (CC_LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
const bool translucent = !layer->isOpaque();
- const Rect bounds(layer->visibleBounds());
+ Rect bounds(layer->computeBounds());
visibleRegion.set(bounds);
- visibleRegion.andSelf(screenRegion);
if (!visibleRegion.isEmpty()) {
// Remove the transparent area from the visible region
if (translucent) {
- visibleRegion.subtractSelf(layer->transparentRegionScreen);
+ Region transparentRegionScreen;
+ const Transform tr(s.transform);
+ if (tr.transformed()) {
+ if (tr.preserveRects()) {
+ // transform the transparent region
+ transparentRegionScreen = tr.transform(s.transparentRegion);
+ } else {
+ // transformation too complex, can't do the
+ // transparent region optimization.
+ transparentRegionScreen.clear();
+ }
+ } else {
+ transparentRegionScreen = s.transparentRegion;
+ }
+ visibleRegion.subtractSelf(transparentRegionScreen);
}
// compute the opaque region
- const int32_t layerOrientation = layer->getOrientation();
+ const int32_t layerOrientation = s.transform.getOrientation();
if (s.alpha==255 && !translucent &&
((layerOrientation & Transform::ROT_INVALID) == false)) {
// the opaque region is the layer's footprint
@@ -740,7 +791,7 @@
// we need to invalidate the whole region
dirty = visibleRegion;
// as well, as the old visible region
- dirty.orSelf(layer->visibleRegionScreen);
+ dirty.orSelf(layer->visibleRegion);
layer->contentDirty = false;
} else {
/* compute the exposed region:
@@ -756,8 +807,8 @@
* exposed because of a resize.
*/
const Region newExposed = visibleRegion - coveredRegion;
- const Region oldVisibleRegion = layer->visibleRegionScreen;
- const Region oldCoveredRegion = layer->coveredRegionScreen;
+ const Region oldVisibleRegion = layer->visibleRegion;
+ const Region oldCoveredRegion = layer->coveredRegion;
const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
}
@@ -779,63 +830,51 @@
}
}
- // invalidate the areas where a layer was removed
- dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
- mDirtyRegionRemovedLayer.clear();
-
mSecureFrameBuffer = secureFrameBuffer;
opaqueRegion = aboveOpaqueLayers;
}
-
-void SurfaceFlinger::commitTransaction()
-{
- if (!mLayersPendingRemoval.isEmpty()) {
- // Notify removed layers now that they can't be drawn from
- for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
- mLayersPendingRemoval[i]->onRemoved();
- }
- mLayersPendingRemoval.clear();
- }
-
- mDrawingState = mCurrentState;
- mTransationPending = false;
- mTransactionCV.broadcast();
-}
-
-void SurfaceFlinger::handlePageFlip()
+Region SurfaceFlinger::handlePageFlip()
{
ATRACE_CALL();
- const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here
- const Region screenRegion(hw.bounds());
+ Region dirtyRegion;
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
- const bool visibleRegions = lockPageFlip(currentLayers);
- if (visibleRegions || mVisibleRegionsDirty) {
- Region opaqueRegion;
- computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
+ bool visibleRegions = false;
+ const size_t count = currentLayers.size();
+ sp<LayerBase> const* layers = currentLayers.array();
+ for (size_t i=0 ; i<count ; i++) {
+ const sp<LayerBase>& layer(layers[i]);
+ dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) );
+ }
- /*
- * rebuild the visible layer list
- */
- const size_t count = currentLayers.size();
- mVisibleLayersSortedByZ.clear();
- mVisibleLayersSortedByZ.setCapacity(count);
- for (size_t i=0 ; i<count ; i++) {
- if (!currentLayers[i]->visibleRegionScreen.isEmpty())
- mVisibleLayersSortedByZ.add(currentLayers[i]);
- }
+ if (visibleRegions || mVisibleRegionsDirty) {
+ Region opaqueRegion;
+ computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion);
- mWormholeRegion = screenRegion.subtract(opaqueRegion);
- mVisibleRegionsDirty = false;
- invalidateHwcGeometry();
+ /*
+ * rebuild the visible layer list
+ */
+
+ // XXX: mVisibleLayersSortedByZ should be per-screen
+ const size_t count = currentLayers.size();
+ mVisibleLayersSortedByZ.clear();
+ mVisibleLayersSortedByZ.setCapacity(count);
+ for (size_t i=0 ; i<count ; i++) {
+ if (!currentLayers[i]->visibleRegion.isEmpty())
+ mVisibleLayersSortedByZ.add(currentLayers[i]);
}
- unlockPageFlip(currentLayers);
+ // FIXME: mWormholeRegion needs to be calculated per screen
+ const DisplayHardware& hw(getDefaultDisplayHardware()); // XXX: we can't keep that here
+ mWormholeRegion = Region(hw.getBounds()).subtract(
+ hw.getTransform().transform(opaqueRegion) );
+ mVisibleRegionsDirty = false;
+ invalidateHwcGeometry();
+ }
- mDirtyRegion.orSelf(getAndClearInvalidateRegion());
- mDirtyRegion.andSelf(screenRegion);
+ return dirtyRegion;
}
void SurfaceFlinger::invalidateHwcGeometry()
@@ -843,30 +882,6 @@
mHwWorkListDirty = true;
}
-bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
-{
- bool recomputeVisibleRegions = false;
- size_t count = currentLayers.size();
- sp<LayerBase> const* layers = currentLayers.array();
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(layers[i]);
- layer->lockPageFlip(recomputeVisibleRegions);
- }
- return recomputeVisibleRegions;
-}
-
-void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
-{
- const DisplayHardware& hw(getDefaultDisplayHardware()); // FIXME: it's a problem we need DisplayHardware here
- const Transform& planeTransform(hw.getTransform());
- const size_t count = currentLayers.size();
- sp<LayerBase> const* layers = currentLayers.array();
- for (size_t i=0 ; i<count ; i++) {
- const sp<LayerBase>& layer(layers[i]);
- layer->unlockPageFlip(planeTransform, mDirtyRegion);
- }
-}
-
void SurfaceFlinger::handleRefresh()
{
bool needInvalidate = false;
@@ -896,7 +911,7 @@
HWComposer::LayerListIterator cur = hwc.begin();
const HWComposer::LayerListIterator end = hwc.end();
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
- currentLayers[i]->setGeometry(*cur);
+ currentLayers[i]->setGeometry(hw, *cur);
if (mDebugDisableHWC || mDebugRegion) {
cur->setSkip(true);
}
@@ -1012,9 +1027,10 @@
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size();
+ const Transform& tr = hw.getTransform();
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<LayerBase>& layer(layers[i]);
- const Region clip(dirty.intersect(layer->visibleRegionScreen));
+ const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
if (!clip.isEmpty()) {
if (cur->getCompositionType() == HWC_OVERLAY) {
if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3e27564..91cc6a5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -129,6 +129,9 @@
GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
void onMessageReceived(int32_t what);
+ void handleMessageTransaction();
+ void handleMessageInvalidate();
+ void handleMessageRefresh();
status_t postMessageAsync(const sp<MessageBase>& msg,
nsecs_t reltime=0, uint32_t flags = 0);
@@ -237,17 +240,23 @@
private:
void waitForEvent();
- void handleTransaction(uint32_t transactionFlags);
- void handleTransactionLocked(uint32_t transactionFlags);
+ Region handleTransaction(uint32_t transactionFlags);
+ Region handleTransactionLocked(uint32_t transactionFlags);
void computeVisibleRegions(
const LayerVector& currentLayers,
Region& dirtyRegion,
Region& wormholeRegion);
- void handlePageFlip();
- bool lockPageFlip(const LayerVector& currentLayers);
- void unlockPageFlip(const LayerVector& currentLayers);
+ /* handlePageFilp: this is were we latch a new buffer
+ * if available and compute the dirty region.
+ * The return value is the dirty region expressed in the
+ * window manager's coordinate space (or the layer's state
+ * space, which is the same thing), in particular the dirty
+ * region is independent from a specific display's orientation.
+ */
+ Region handlePageFlip();
+
void handleRefresh();
void handleWorkList(const DisplayHardware& hw);
void handleRepaint(const DisplayHardware& hw);