diff options
35 files changed, 593 insertions, 529 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 4f32146..6f4be09 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -66,16 +66,11 @@ public: eMatrixChanged = 0x00000010, eTransparentRegionChanged = 0x00000020, eVisibilityChanged = 0x00000040, - eFreezeTintChanged = 0x00000080, eCropChanged = 0x00000100, }; enum { eLayerHidden = 0x01, - eLayerFrozen = 0x02, - eLayerDither = 0x04, - eLayerFilter = 0x08, - eLayerBlurFreeze = 0x10 }; enum { 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 @@ public: 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 @@ public: //! 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 @@ public: 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 @@ struct CryptoPlugin { // 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 @@ struct layer_state_t { 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 @@ struct layer_state_t { 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/SystemClock.h b/include/utils/SystemClock.h index 7c319be..d75264c 100644 --- a/include/utils/SystemClock.h +++ b/include/utils/SystemClock.h @@ -25,6 +25,7 @@ namespace android { int setCurrentTimeMillis(int64_t millis); int64_t uptimeMillis(); int64_t elapsedRealtime(); +int64_t elapsedRealtimeNano(); }; // namespace android diff --git a/include/utils/Timers.h b/include/utils/Timers.h index 8b4d322..92f66c9 100644 --- a/include/utils/Timers.h +++ b/include/utils/Timers.h @@ -78,9 +78,10 @@ enum { SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock - SYSTEM_TIME_THREAD = 3 // high-resolution per-thread clock + SYSTEM_TIME_THREAD = 3, // high-resolution per-thread clock + SYSTEM_TIME_BOOTTIME = 4 // same as SYSTEM_TIME_MONOTONIC, but including CPU suspend time }; - + // return the system-time according to the specified clock #ifdef __cplusplus nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC); 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 @@ status_t SurfaceControl::show(int32_t layer) { 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 @@ status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtd 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 @@ public: 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 @@ status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client, 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 @@ status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) { 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 @@ status_t SurfaceComposerClient::show(SurfaceID id, int32_t) { 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 @@ ssize_t SurfaceComposerClient::getNumberOfDisplays() // ---------------------------------------------------------------------------- -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/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp index 8b8ac10..53e0626 100644 --- a/libs/utils/SystemClock.cpp +++ b/libs/utils/SystemClock.cpp @@ -106,7 +106,22 @@ int64_t uptimeMillis() */ int64_t elapsedRealtime() { + return nanoseconds_to_milliseconds(elapsedRealtimeNano()); +} + +/* + * native public static long elapsedRealtimeNano(); + */ +int64_t elapsedRealtimeNano() +{ #ifdef HAVE_ANDROID_OS + struct timespec ts; + int result = clock_gettime(CLOCK_BOOTTIME, &ts); + if (result == 0) { + return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; + } + + // CLOCK_BOOTTIME doesn't exist, fallback to /dev/alarm static int s_fd = -1; if (s_fd == -1) { @@ -114,25 +129,20 @@ int64_t elapsedRealtime() if (android_atomic_cmpxchg(-1, fd, &s_fd)) { close(fd); } + result = ioctl(s_fd, + ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); } - struct timespec ts; - int result = ioctl(s_fd, - ANDROID_ALARM_GET_TIME(ANDROID_ALARM_ELAPSED_REALTIME), &ts); - if (result == 0) { - int64_t when = seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; - return (int64_t) nanoseconds_to_milliseconds(when); - } else { - // XXX: there was an error, probably because the driver didn't - // exist ... this should return - // a real error, like an exception! - int64_t when = systemTime(SYSTEM_TIME_MONOTONIC); - return (int64_t) nanoseconds_to_milliseconds(when); + return seconds_to_nanoseconds(ts.tv_sec) + ts.tv_nsec; } + + // XXX: there was an error, probably because the driver didn't + // exist ... this should return + // a real error, like an exception! + return systemTime(SYSTEM_TIME_MONOTONIC); #else - int64_t when = systemTime(SYSTEM_TIME_MONOTONIC); - return (int64_t) nanoseconds_to_milliseconds(when); + return systemTime(SYSTEM_TIME_MONOTONIC); #endif } diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp index 64b4701..d4f8516 100644 --- a/libs/utils/Timers.cpp +++ b/libs/utils/Timers.cpp @@ -39,7 +39,8 @@ nsecs_t systemTime(int clock) CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, - CLOCK_THREAD_CPUTIME_ID + CLOCK_THREAD_CPUTIME_ID, + CLOCK_BOOTTIME }; struct timespec t; t.tv_sec = t.tv_nsec = 0; diff --git a/opengl/tools/glgen/src/EGLCodeEmitter.java b/opengl/tools/glgen/src/EGLCodeEmitter.java index 1691b65..300f776 100644 --- a/opengl/tools/glgen/src/EGLCodeEmitter.java +++ b/opengl/tools/glgen/src/EGLCodeEmitter.java @@ -44,7 +44,7 @@ public class EGLCodeEmitter extends JniCodeEmitter { mUseContextPointer = false; mUseStaticMethods = true; mUseSimpleMethodNames = true; - mUseHideCommentForAPI = true; + mUseHideCommentForAPI = false; } public void emitCode(CFunc cfunc, String original) { diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java index af98889..726dc61 100644 --- a/opengl/tools/glgen/src/JniCodeEmitter.java +++ b/opengl/tools/glgen/src/JniCodeEmitter.java @@ -939,10 +939,13 @@ public class JniCodeEmitter { // Emit a single _array or multiple _XXXArray variables if (numBufferArgs == 1) { out.println(indent + "jarray _array = (jarray) 0;"); + out.println(indent + "jint _bufferOffset = (jint) 0;"); } else { for (int i = 0; i < numBufferArgs; i++) { out.println(indent + "jarray _" + bufferArgNames.get(i) + "Array = (jarray) 0;"); + out.println(indent + "jint _" + bufferArgNames.get(i) + + "BufferOffset = (jint) 0;"); } } if (!isVoid) { @@ -1075,7 +1078,6 @@ public class JniCodeEmitter { // Emit 'GetPrimitiveArrayCritical' for non-object arrays // Emit 'GetPointer' calls for Buffer pointers - int bufArgIdx = 0; if (nonPrimitiveArgs.size() > 0) { for (int i = 0; i < nonPrimitiveArgs.size(); i++) { int idx = nonPrimitiveArgs.get(i).intValue(); @@ -1168,7 +1170,9 @@ public class JniCodeEmitter { out.println(); } else if (jfunc.getArgType(idx).isBuffer()) { String array = numBufferArgs <= 1 ? "_array" : - "_" + bufferArgNames.get(bufArgIdx++) + "Array"; + "_" + cfunc.getArgName(cIndex) + "Array"; + String bufferOffset = numBufferArgs <= 1 ? "_bufferOffset" : + "_" + cfunc.getArgName(cIndex) + "BufferOffset"; boolean nullAllowed = isNullAllowed(cfunc) || isPointerFunc; if (nullAllowed) { @@ -1194,7 +1198,7 @@ public class JniCodeEmitter { cfunc.getArgType(cIndex).getDeclaration() + ")getPointer(_env, " + cname + - "_buf, &" + array + ", &" + remaining + + "_buf, &" + array + ", &" + remaining + ", &" + bufferOffset + ");"); } @@ -1209,6 +1213,28 @@ public class JniCodeEmitter { } } + // Emit 'GetPrimitiveArrayCritical' for pointers if needed + if (nonPrimitiveArgs.size() > 0) { + for (int i = 0; i < nonPrimitiveArgs.size(); i++) { + int idx = nonPrimitiveArgs.get(i).intValue(); + int cIndex = jfunc.getArgCIndex(idx); + + if(!jfunc.getArgType(idx).isBuffer() || isPointerFunc) continue; + + String cname = cfunc.getArgName(cIndex); + String bufferOffset = numBufferArgs <= 1 ? "_bufferOffset" : + "_" + cname + "BufferOffset"; + String array = numBufferArgs <= 1 ? "_array" : + "_" + cfunc.getArgName(cIndex) + "Array"; + + out.println(indent + "if (" + cname +" == NULL) {"); + out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->GetPrimitiveArrayCritical(" + array + ", (jboolean *) 0);"); + out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");"); + out.println(indent + "}"); + } + } + + if (!isVoid) { out.print(indent + "_returnValue = "); } else { @@ -1252,7 +1278,7 @@ public class JniCodeEmitter { out.print("_native"); } - if (cfunc.getArgType(i).isEGLHandle() && + if (cfunc.getArgType(i).isEGLHandle() && !cfunc.getArgType(i).isPointer()){ out.print(cfunc.getArgName(i)+"_native"); } else { @@ -1279,7 +1305,7 @@ public class JniCodeEmitter { needsExit = false; } - bufArgIdx = 0; + if (nonPrimitiveArgs.size() > 0) { for (int i = nonPrimitiveArgs.size() - 1; i >= 0; i--) { int idx = nonPrimitiveArgs.get(i).intValue(); @@ -1307,7 +1333,7 @@ public class JniCodeEmitter { } else if (jfunc.getArgType(idx).isBuffer()) { if (! isPointerFunc) { String array = numBufferArgs <= 1 ? "_array" : - "_" + bufferArgNames.get(bufArgIdx++) + "Array"; + "_" + cfunc.getArgName(cIndex) + "Array"; out.println(indent + "if (" + array + ") {"); out.println(indent + indent + "releasePointer(_env, " + array + ", " + diff --git a/opengl/tools/glgen/static/egl/EGLConfig.java b/opengl/tools/glgen/static/egl/EGLConfig.java index d9aebfc..d457c9f 100644 --- a/opengl/tools/glgen/static/egl/EGLConfig.java +++ b/opengl/tools/glgen/static/egl/EGLConfig.java @@ -18,10 +18,11 @@ package android.opengl; /** - * @hide + * Wrapper class for native EGLConfig objects. + * */ public class EGLConfig extends EGLObjectHandle { - public EGLConfig(int handle) { + private EGLConfig(int handle) { super(handle); } @@ -33,9 +34,4 @@ public class EGLConfig extends EGLObjectHandle { 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 index 7b194f3..41b8ef1 100644 --- a/opengl/tools/glgen/static/egl/EGLContext.java +++ b/opengl/tools/glgen/static/egl/EGLContext.java @@ -18,10 +18,11 @@ package android.opengl; /** - * @hide + * Wrapper class for native EGLContext objects. + * */ public class EGLContext extends EGLObjectHandle { - public EGLContext(int handle) { + private EGLContext(int handle) { super(handle); } @@ -33,9 +34,4 @@ public class EGLContext extends EGLObjectHandle { 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 index a090cf0..17d1a64 100644 --- a/opengl/tools/glgen/static/egl/EGLDisplay.java +++ b/opengl/tools/glgen/static/egl/EGLDisplay.java @@ -18,10 +18,11 @@ package android.opengl; /** - * @hide + * Wrapper class for native EGLDisplay objects. + * */ public class EGLDisplay extends EGLObjectHandle { - public EGLDisplay(int handle) { + private EGLDisplay(int handle) { super(handle); } @@ -33,9 +34,4 @@ public class EGLDisplay extends EGLObjectHandle { 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 index 01f9bd4..d2710de 100644 --- a/opengl/tools/glgen/static/egl/EGLObjectHandle.java +++ b/opengl/tools/glgen/static/egl/EGLObjectHandle.java @@ -18,16 +18,30 @@ package android.opengl; /** - * @hide + * Base class for wrapped EGL objects. + * */ public abstract class EGLObjectHandle { private final int mHandle; - public EGLObjectHandle(int handle) { + protected EGLObjectHandle(int handle) { mHandle = handle; } + /** + * Returns the native handle of the wrapped EGL object. This handle can be + * cast to the corresponding native type on the native side. + * + * For example, EGLDisplay dpy = (EGLDisplay)handle; + * + * @return the native handle of the wrapped EGL object. + */ public int getHandle() { return mHandle; } + + @Override + public int hashCode() { + return getHandle(); + } } diff --git a/opengl/tools/glgen/static/egl/EGLSurface.java b/opengl/tools/glgen/static/egl/EGLSurface.java index 4800a64..65bec4f 100644 --- a/opengl/tools/glgen/static/egl/EGLSurface.java +++ b/opengl/tools/glgen/static/egl/EGLSurface.java @@ -18,10 +18,11 @@ package android.opengl; /** - * @hide + * Wrapper class for native EGLSurface objects. + * */ public class EGLSurface extends EGLObjectHandle { - public EGLSurface(int handle) { + private EGLSurface(int handle) { super(handle); } @@ -33,9 +34,4 @@ public class EGLSurface extends EGLObjectHandle { 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 index 9330c99..0c29d5c 100644 --- a/opengl/tools/glgen/stubs/egl/EGL14Header.java-if +++ b/opengl/tools/glgen/stubs/egl/EGL14Header.java-if @@ -23,10 +23,10 @@ import android.view.Surface; import android.view.SurfaceView; import android.view.SurfaceHolder; - /** -* @hide -*/ + * EGL 1.4 + * + */ public class EGL14 { public static final int EGL_DEFAULT_DISPLAY = 0; diff --git a/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp index 5d418d7..172c0e7 100644 --- a/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp +++ b/opengl/tools/glgen/stubs/gles11/GLES10ExtcHeader.cpp @@ -62,14 +62,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -84,11 +82,10 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return (void *) ((char *) data + offset); + return NULL; } diff --git a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp index 35a3c33..4ef815b 100644 --- a/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp +++ b/opengl/tools/glgen/stubs/gles11/GLES10cHeader.cpp @@ -74,14 +74,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) } static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -96,11 +94,10 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return (void *) ((char *) data + offset); + return NULL; } static void diff --git a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp index 9b29a44..0df95f4 100644 --- a/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp +++ b/opengl/tools/glgen/stubs/gles11/GLES11ExtcHeader.cpp @@ -71,14 +71,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -93,11 +91,9 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - - return (void *) ((char *) data + offset); + return NULL; } diff --git a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp index 823079f..dd860d5 100644 --- a/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp +++ b/opengl/tools/glgen/stubs/gles11/GLES11cHeader.cpp @@ -69,14 +69,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -91,11 +89,10 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return (void *) ((char *) data + offset); + return NULL; } diff --git a/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp index 13a2577..996f441 100644 --- a/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp +++ b/opengl/tools/glgen/stubs/gles11/GLES20cHeader.cpp @@ -62,14 +62,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -84,11 +82,10 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass, getBaseArrayID, buffer); - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return (void *) ((char *) data + offset); + return NULL; } diff --git a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp index f7315ee..cc10336 100644 --- a/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp +++ b/opengl/tools/glgen/stubs/jsr239/GLCHeader.cpp @@ -113,14 +113,12 @@ nativeClassInit(JNIEnv *_env, jclass glImplClass) } static void * -getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) +getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset) { jint position; jint limit; jint elementSizeShift; jlong pointer; - jint offset; - void *data; position = _env->GetIntField(buffer, positionID); limit = _env->GetIntField(buffer, limitID); @@ -138,11 +136,10 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining) if (*array == NULL) { return (void*) NULL; } - offset = _env->CallStaticIntMethod(nioAccessClass, + *offset = _env->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetID, buffer); - data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0); - return (void *) ((char *) data + offset); + return NULL; } static void @@ -180,10 +177,12 @@ getDirectBufferPointer(JNIEnv *_env, jobject buffer) { if (allowIndirectBuffers(_env)) { jarray array = 0; jint remaining; - buf = getPointer(_env, buffer, &array, &remaining); + jint offset; + buf = getPointer(_env, buffer, &array, &remaining, &offset); if (array) { releasePointer(_env, array, buf, 0); } + buf = buf + offset; } else { jniThrowException(_env, "java/lang/IllegalArgumentException", "Must use a native order direct Buffer"); diff --git a/services/surfaceflinger/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware.cpp index eac9e04..af33a89 100644 --- a/services/surfaceflinger/DisplayHardware.cpp +++ b/services/surfaceflinger/DisplayHardware.cpp @@ -31,6 +31,7 @@ #include <EGL/eglext.h> #include <hardware/gralloc.h> +#include <private/gui/SharedBufferStack.h> #include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/DisplayHardwareBase.h" @@ -40,8 +41,9 @@ #include "GLExtensions.h" #include "SurfaceFlinger.h" +// ---------------------------------------------------------------------------- using namespace android; - +// ---------------------------------------------------------------------------- static __attribute__((noinline)) void checkGLErrors() @@ -88,6 +90,8 @@ void checkEGLErrors(const char* token) } } +// ---------------------------------------------------------------------------- + /* * Initialize the display to the specified values. * @@ -95,79 +99,78 @@ void checkEGLErrors(const char* token) DisplayHardware::DisplayHardware( const sp<SurfaceFlinger>& flinger, - uint32_t dpy) - : DisplayHardwareBase(flinger, dpy), - mFlinger(flinger), mFlags(0), mHwc(0) + int display, + const sp<SurfaceTextureClient>& surface, + EGLConfig config) + : DisplayHardwareBase(flinger, display), + mFlinger(flinger), + mDisplayId(display), + mHwc(0), + mNativeWindow(surface), + mFlags(0), + mSecureLayerVisible(false) { - init(dpy); + init(config); } -DisplayHardware::~DisplayHardware() -{ - fini(); +DisplayHardware::~DisplayHardware() { } -float DisplayHardware::getDpiX() const { return mDpiX; } -float DisplayHardware::getDpiY() const { return mDpiY; } -float DisplayHardware::getDensity() const { return mDensity; } -float DisplayHardware::getRefreshRate() const { return mRefreshRate; } -int DisplayHardware::getWidth() const { return mDisplayWidth; } -int DisplayHardware::getHeight() const { return mDisplayHeight; } -PixelFormat DisplayHardware::getFormat() const { return mFormat; } -uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; } - -uint32_t DisplayHardware::getMaxViewportDims() const { - return mMaxViewportDims[0] < mMaxViewportDims[1] ? - mMaxViewportDims[0] : mMaxViewportDims[1]; +float DisplayHardware::getDpiX() const { + return mDpiX; } -static status_t selectConfigForPixelFormat( - EGLDisplay dpy, - EGLint const* attrs, - PixelFormat format, - EGLConfig* outConfig) -{ - EGLConfig config = NULL; - EGLint numConfigs = -1, n=0; - eglGetConfigs(dpy, NULL, 0, &numConfigs); - EGLConfig* const configs = new EGLConfig[numConfigs]; - eglChooseConfig(dpy, attrs, configs, numConfigs, &n); - for (int i=0 ; i<n ; i++) { - EGLint nativeVisualId = 0; - eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); - if (nativeVisualId>0 && format == nativeVisualId) { - *outConfig = configs[i]; - delete [] configs; - return NO_ERROR; - } - } - delete [] configs; - return NAME_NOT_FOUND; +float DisplayHardware::getDpiY() const { + return mDpiY; } +float DisplayHardware::getDensity() const { + return mDensity; +} + +float DisplayHardware::getRefreshRate() const { + return mRefreshRate; +} -void DisplayHardware::init(uint32_t dpy) +int DisplayHardware::getWidth() const { + return mDisplayWidth; +} + +int DisplayHardware::getHeight() const { + return mDisplayHeight; +} + +PixelFormat DisplayHardware::getFormat() const { + return mFormat; +} + +EGLSurface DisplayHardware::getEGLSurface() const { + return mSurface; +} + +void DisplayHardware::init(EGLConfig config) { - mNativeWindow = new FramebufferSurface(); - framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); - if (!fbDev) { - ALOGE("Display subsystem failed to initialize. check logs. exiting..."); - exit(0); + ANativeWindow* const window = mNativeWindow.get(); + + int concreteType; + window->query(window, NATIVE_WINDOW_CONCRETE_TYPE, &concreteType); + if (concreteType == NATIVE_WINDOW_FRAMEBUFFER) { + mFramebufferSurface = static_cast<FramebufferSurface *>(mNativeWindow.get()); } int format; - ANativeWindow const * const window = mNativeWindow.get(); window->query(window, NATIVE_WINDOW_FORMAT, &format); - mDpiX = mNativeWindow->xdpi; - mDpiY = mNativeWindow->ydpi; - mRefreshRate = fbDev->fps; - - if (mDpiX == 0 || mDpiY == 0) { - ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), " - "defaulting to 160 dpi", mDpiX, mDpiY); - mDpiX = mDpiY = 160; + mDpiX = window->xdpi; + mDpiY = window->ydpi; + if (mFramebufferSurface != NULL) { + mRefreshRate = mFramebufferSurface->getRefreshRate(); + } else { + mRefreshRate = 60; } + mRefreshPeriod = nsecs_t(1e9 / mRefreshRate); + + // TODO: Not sure if display density should handled by SF any longer class Density { static int getDensityFromProperty(char const* propName) { char property[PROPERTY_VALUE_MAX]; @@ -183,173 +186,52 @@ void DisplayHardware::init(uint32_t dpy) static int getBuildDensity() { return getDensityFromProperty("ro.sf.lcd_density"); } }; - - // The density of the device is provided by a build property mDensity = Density::getBuildDensity() / 160.0f; - if (mDensity == 0) { // the build doesn't provide a density -- this is wrong! // use xdpi instead ALOGE("ro.sf.lcd_density must be defined as a build property"); mDensity = mDpiX / 160.0f; } - if (Density::getEmuDensity()) { // if "qemu.sf.lcd_density" is specified, it overrides everything mDpiX = mDpiY = mDensity = Density::getEmuDensity(); mDensity /= 160.0f; } - - - /* FIXME: this is a temporary HACK until we are able to report the refresh rate - * properly from the HAL. The WindowManagerService now relies on this value. + /* + * Create our display's surface */ -#ifndef REFRESH_RATE - mRefreshRate = fbDev->fps; -#else - mRefreshRate = REFRESH_RATE; -#warning "refresh rate set via makefile to REFRESH_RATE" -#endif - - mRefreshPeriod = nsecs_t(1e9 / mRefreshRate); - EGLint w, h, dummy; - EGLint numConfigs=0; EGLSurface surface; - EGLContext context; - EGLBoolean result; - status_t err; - - // initialize EGL - EGLint attribs[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RECORDABLE_ANDROID, EGL_TRUE, - EGL_NONE - }; - - // TODO: all the extensions below should be queried through - // eglGetProcAddress(). - + EGLint w, h; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - eglInitialize(display, NULL, NULL); - eglGetConfigs(display, NULL, 0, &numConfigs); - - EGLConfig config = NULL; - err = selectConfigForPixelFormat(display, attribs, format, &config); - if (err) { - // maybe we failed because of EGL_RECORDABLE_ANDROID - ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); - attribs[2] = EGL_NONE; - err = selectConfigForPixelFormat(display, attribs, format, &config); - } - - ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); - - EGLint r,g,b,a; - eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r); - eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); - eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b); - eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); - - if (mNativeWindow->isUpdateOnDemand()) { - mFlags |= PARTIAL_UPDATES; - } - - if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { - if (dummy == EGL_SLOW_CONFIG) - mFlags |= SLOW_CONFIG; - } - - /* - * Create our main surface - */ - - surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); + surface = eglCreateWindowSurface(display, config, window, NULL); eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth); eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight); - if (mFlags & PARTIAL_UPDATES) { - // if we have partial updates, we definitely don't need to - // preserve the backbuffer, which may be costly. - eglSurfaceAttrib(display, surface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); + if (mFramebufferSurface != NULL) { + if (mFramebufferSurface->isUpdateOnDemand()) { + mFlags |= PARTIAL_UPDATES; + // if we have partial updates, we definitely don't need to + // preserve the backbuffer, which may be costly. + eglSurfaceAttrib(display, surface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); + } } - /* - * Create our OpenGL ES context - */ - - EGLint contextAttributes[] = { -#ifdef EGL_IMG_context_priority -#ifdef HAS_CONTEXT_PRIORITY -#warning "using EGL_IMG_context_priority" - EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, -#endif -#endif - EGL_NONE, EGL_NONE - }; - context = eglCreateContext(display, config, NULL, contextAttributes); - mDisplay = display; - mConfig = config; mSurface = surface; - mContext = context; - mFormat = fbDev->format; + mFormat = format; mPageFlipCount = 0; - /* - * Gather OpenGL ES extensions - */ - - result = eglMakeCurrent(display, surface, surface, context); - if (!result) { - ALOGE("Couldn't create a working GLES context. check logs. exiting..."); - exit(0); - } - - GLExtensions& extensions(GLExtensions::getInstance()); - extensions.initWithGLStrings( - glGetString(GL_VENDOR), - glGetString(GL_RENDERER), - glGetString(GL_VERSION), - glGetString(GL_EXTENSIONS), - eglQueryString(display, EGL_VENDOR), - eglQueryString(display, EGL_VERSION), - eglQueryString(display, EGL_EXTENSIONS)); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); - - ALOGI("EGL informations:"); - ALOGI("# of configs : %d", numConfigs); - ALOGI("vendor : %s", extensions.getEglVendor()); - ALOGI("version : %s", extensions.getEglVersion()); - ALOGI("extensions: %s", extensions.getEglExtension()); - ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); - ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); - - ALOGI("OpenGL informations:"); - ALOGI("vendor : %s", extensions.getVendor()); - ALOGI("renderer : %s", extensions.getRenderer()); - ALOGI("version : %s", extensions.getVersion()); - ALOGI("extensions: %s", extensions.getExtension()); - ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); - ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); - ALOGI("flags = %08x", mFlags); - - // Unbind the context from this thread - eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - // initialize the H/W composer mHwc = new HWComposer(mFlinger, *this, mRefreshPeriod); if (mHwc->initCheck() == NO_ERROR) { mHwc->setFrameBuffer(mDisplay, mSurface); } - // initialize the display orientation transform. // it's a constant that should come from the display driver. int displayOrientation = ISurfaceComposer::eOrientationDefault; @@ -378,6 +260,20 @@ void DisplayHardware::init(uint32_t dpy) mLogicalDisplayHeight = h; } DisplayHardware::setOrientation(ISurfaceComposer::eOrientationDefault); + + // initialize the shared control block + surface_flinger_cblk_t* const scblk = mFlinger->getControlBlock(); + scblk->connected |= 1 << mDisplayId; + display_cblk_t* dcblk = &scblk->displays[mDisplayId]; + memset(dcblk, 0, sizeof(display_cblk_t)); + dcblk->w = w; // XXX: plane.getWidth(); + dcblk->h = h; // XXX: plane.getHeight(); + dcblk->format = format; + dcblk->orientation = ISurfaceComposer::eOrientationDefault; + dcblk->xdpi = mDpiX; + dcblk->ydpi = mDpiY; + dcblk->fps = mRefreshRate; + dcblk->density = mDensity; } void DisplayHardware::setVSyncHandler(const sp<VSyncHandler>& handler) { @@ -411,19 +307,6 @@ HWComposer& DisplayHardware::getHwComposer() const { return *mHwc; } -/* - * Clean up. Throw out our local state. - * - * (It's entirely possible we'll never get here, since this is meant - * for real hardware, which doesn't restart.) - */ - -void DisplayHardware::fini() -{ - eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglTerminate(mDisplay); -} - void DisplayHardware::releaseScreen() const { DisplayHardwareBase::releaseScreen(); @@ -434,6 +317,9 @@ void DisplayHardware::releaseScreen() const void DisplayHardware::acquireScreen() const { + if (mHwc->initCheck() == NO_ERROR) { + mHwc->acquire(); + } DisplayHardwareBase::acquireScreen(); } @@ -455,7 +341,10 @@ nsecs_t DisplayHardware::getRefreshPeriod() const { } status_t DisplayHardware::compositionComplete() const { - return mNativeWindow->compositionComplete(); + if (mFramebufferSurface == NULL) { + return NO_ERROR; + } + return mFramebufferSurface->compositionComplete(); } void DisplayHardware::flip(const Region& dirty) const @@ -475,7 +364,9 @@ void DisplayHardware::flip(const Region& dirty) const #endif if (mFlags & PARTIAL_UPDATES) { - mNativeWindow->setUpdateRectangle(dirty.getBounds()); + if (mFramebufferSurface != NULL) { + mFramebufferSurface->setUpdateRectangle(dirty.getBounds()); + } } mPageFlipCount++; @@ -486,10 +377,6 @@ void DisplayHardware::flip(const Region& dirty) const eglSwapBuffers(dpy, surface); } checkEGLErrors("eglSwapBuffers"); - - // for debugging - //glClearColor(1,0,0,0); - //glClear(GL_COLOR_BUFFER_BIT); } uint32_t DisplayHardware::getFlags() const @@ -497,14 +384,31 @@ uint32_t DisplayHardware::getFlags() const return mFlags; } -void DisplayHardware::makeCurrent() const +void DisplayHardware::dump(String8& res) const { - eglMakeCurrent(mDisplay, mSurface, mSurface, mContext); + if (mFramebufferSurface != NULL) { + mFramebufferSurface->dump(res); + } } -void DisplayHardware::dump(String8& res) const -{ - mNativeWindow->dump(res); +// ---------------------------------------------------------------------------- + +void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) { + mVisibleLayersSortedByZ = layers; + size_t count = layers.size(); + for (size_t i=0 ; i<count ; i++) { + if (layers[i]->isSecure()) { + mSecureLayerVisible = true; + } + } +} + +Vector< sp<LayerBase> > DisplayHardware::getVisibleLayersSortedByZ() const { + return mVisibleLayersSortedByZ; +} + +bool DisplayHardware::getSecureLayerVisible() const { + return mSecureLayerVisible; } // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayHardware.h b/services/surfaceflinger/DisplayHardware.h index 3da9f16..029c3da 100644 --- a/services/surfaceflinger/DisplayHardware.h +++ b/services/surfaceflinger/DisplayHardware.h @@ -27,7 +27,6 @@ #include <EGL/egl.h> #include <EGL/eglext.h> -#include "GLExtensions.h" #include "Transform.h" #include "DisplayHardware/DisplayHardwareBase.h" @@ -37,6 +36,7 @@ namespace android { class FramebufferSurface; +class SurfaceTextureClient; class DisplayHardware : public DisplayHardwareBase, @@ -52,15 +52,15 @@ public: }; enum { - COPY_BITS_EXTENSION = 0x00000008, PARTIAL_UPDATES = 0x00020000, // video driver feature - SLOW_CONFIG = 0x00040000, // software SWAP_RECTANGLE = 0x00080000, }; DisplayHardware( const sp<SurfaceFlinger>& flinger, - uint32_t displayIndex); + int dpy, + const sp<SurfaceTextureClient>& surface, + EGLConfig config); virtual ~DisplayHardware(); @@ -79,11 +79,14 @@ public: int getHeight() const; PixelFormat getFormat() const; uint32_t getFlags() const; - uint32_t getMaxTextureSize() const; - uint32_t getMaxViewportDims() const; nsecs_t getRefreshPeriod() const; nsecs_t getRefreshTimestamp() const; - void makeCurrent() const; + + EGLSurface getEGLSurface() const; + + void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers); + Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const; + bool getSecureLayerVisible() const; status_t setOrientation(int orientation); int getOrientation() const { return mOrientation; } @@ -102,7 +105,6 @@ public: uint32_t getPageFlipCount() const; EGLDisplay getEGLDisplay() const { return mDisplay; } - EGLConfig getEGLConfig() const { return mConfig; } void dump(String8& res) const; @@ -117,15 +119,26 @@ public: inline Rect bounds() const { return getBounds(); } private: + void init(EGLConfig config); + virtual void onVSyncReceived(int dpy, nsecs_t timestamp); - void init(uint32_t displayIndex); - void fini(); + /* + * Constants, set during initialization + */ sp<SurfaceFlinger> mFlinger; + int mDisplayId; + HWComposer* mHwc; + PowerHAL mPowerHAL; + // ANativeWindow this display is rendering into + sp<SurfaceTextureClient> mNativeWindow; + // set if mNativeWindow is a FramebufferSurface + sp<FramebufferSurface> mFramebufferSurface; + + EGLDisplay mDisplay; EGLSurface mSurface; EGLContext mContext; - EGLConfig mConfig; float mDpiX; float mDpiY; float mRefreshRate; @@ -135,15 +148,19 @@ private: PixelFormat mFormat; uint32_t mFlags; mutable uint32_t mPageFlipCount; - GLint mMaxViewportDims[2]; - GLint mMaxTextureSize; nsecs_t mRefreshPeriod; mutable nsecs_t mLastHwVSync; - // constant once set - HWComposer* mHwc; - PowerHAL mPowerHAL; + + /* + * Can only accessed from the main thread, these members + * don't need synchronization. + */ + // list of visible layers on that display + Vector< sp<LayerBase> > mVisibleLayersSortedByZ; + // Whether we have a visible secure layer on this display + bool mSecureLayerVisible; // this used to be in GraphicPlane @@ -157,13 +174,12 @@ private: int mUserDisplayWidth; int mUserDisplayHeight; - mutable Mutex mLock; - // protected by mLock + /* + * protected by mLock + */ wp<VSyncHandler> mVSyncHandler; - - sp<FramebufferSurface> mNativeWindow; }; }; // namespace android diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp index 6cfb190..7695e7f 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp @@ -38,6 +38,15 @@ namespace android { // ---------------------------------------------------------------------------- +sp<FramebufferSurface> FramebufferSurface::create() { + sp<FramebufferSurface> result = new FramebufferSurface(); + if (result->fbDev == NULL) { + result = NULL; + } + return result; +} + +// ---------------------------------------------------------------------------- /* * This implements the (main) framebuffer management. This class is used @@ -64,10 +73,19 @@ FramebufferSurface::FramebufferSurface() mUpdateOnDemand = (fbDev->setUpdateRect != 0); const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; - const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; - const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval; const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval; + + if (fbDev->xdpi == 0 || fbDev->ydpi == 0) { + ALOGE("invalid screen resolution from fb HAL (xdpi=%f, ydpi=%f), " + "defaulting to 160 dpi", fbDev->xdpi, fbDev->ydpi); + const_cast<float&>(ANativeWindow::xdpi) = 160; + const_cast<float&>(ANativeWindow::ydpi) = 160; + } else { + const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; + const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; + } + } else { ALOGE("Couldn't get gralloc module"); } @@ -139,6 +157,19 @@ FramebufferSurface::~FramebufferSurface() { } } +float FramebufferSurface::getRefreshRate() const { + /* FIXME: REFRESH_RATE is a temporary HACK until we are able to report the + * refresh rate properly from the HAL. The WindowManagerService now relies + * on this value. + */ +#ifndef REFRESH_RATE + return fbDev->fps; +#else + return REFRESH_RATE; +#warning "refresh rate set via makefile to REFRESH_RATE" +#endif +} + status_t FramebufferSurface::setUpdateRectangle(const Rect& r) { if (!mUpdateOnDemand) { diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h index 5b4fd01..672bfbb 100644 --- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h +++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h @@ -37,11 +37,11 @@ class String8; class FramebufferSurface : public SurfaceTextureClient { public: - FramebufferSurface(); - virtual void onFirstRef(); + static sp<FramebufferSurface> create(); - framebuffer_device_t const * getDevice() const { return fbDev; } + // TODO: this should be coming from HWC + float getRefreshRate() const; bool isUpdateOnDemand() const { return mUpdateOnDemand; } status_t setUpdateRectangle(const Rect& updateRect); @@ -49,7 +49,11 @@ public: void dump(String8& result); +protected: + virtual void onFirstRef(); + private: + FramebufferSurface(); virtual ~FramebufferSurface(); // this class cannot be overloaded virtual int query(int what, int* value) const; diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 4ed692f..122be5e 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -286,11 +286,33 @@ status_t HWComposer::release() const { mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0); } int err = mHwc->set(mHwc, NULL, NULL, NULL); + if (err < 0) { + return (status_t)err; + } + + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + if (mHwc->methods && mHwc->methods->blank) { + err = mHwc->methods->blank(mHwc, 1); + } + } return (status_t)err; } return NO_ERROR; } +status_t HWComposer::acquire() const { + if (mHwc) { + if (hwcHasVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) { + if (mHwc->methods && mHwc->methods->blank) { + int err = mHwc->methods->blank(mHwc, 0); + return (status_t)err; + } + } + } + + return NO_ERROR; +} + status_t HWComposer::disable() { if (mHwc) { free(mList); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index a662b25..5cde7fb 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -71,9 +71,12 @@ public: // commits the list status_t commit() const; - // release hardware resources + // release hardware resources and blank screen status_t release() const; + // acquire hardware resources and unblank screen + status_t acquire() const; + // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED. status_t createWorkList(size_t numLayers); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index a09b5c7..b2f2683 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -182,11 +182,8 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, return err; } - // the display's pixel format - // XXX: we shouldn't rely on the DisplayHardware to do this - const DisplayHardware& hw(mFlinger->getDefaultDisplayHardware()); uint32_t const maxSurfaceDims = min( - hw.getMaxTextureSize(), hw.getMaxViewportDims()); + mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims()); // never allow a surface larger than what our underlying GL implementation // can handle. diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h index d227b2d..c689297 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -25,6 +25,7 @@ #include <GLES/gl.h> #include <utils/RefBase.h> +#include <utils/String8.h> #include <ui/Region.h> diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 6c900be..840222c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -59,6 +59,7 @@ #include "LayerScreenshot.h" #include "SurfaceFlinger.h" +#include "DisplayHardware/FramebufferSurface.h" #include "DisplayHardware/HWComposer.h" #include <private/android_filesystem_config.h> @@ -98,7 +99,6 @@ SurfaceFlinger::SurfaceFlinger() mDebugInTransaction(0), mLastTransactionTime(0), mBootFinished(false), - mSecureFrameBuffer(0), mExternalDisplaySurface(EGL_NO_SURFACE) { init(); @@ -142,6 +142,9 @@ void SurfaceFlinger::onFirstRef() SurfaceFlinger::~SurfaceFlinger() { glDeleteTextures(1, &mWormholeTexName); + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(display); } void SurfaceFlinger::binderDied(const wp<IBinder>& who) @@ -198,59 +201,95 @@ void SurfaceFlinger::bootFinished() property_set("service.bootanim.exit", "1"); } -static inline uint16_t pack565(int r, int g, int b) { - return (r<<11)|(g<<5)|b; -} - -status_t SurfaceFlinger::readyToRun() +status_t SurfaceFlinger::selectConfigForPixelFormat( + EGLDisplay dpy, + EGLint const* attrs, + PixelFormat format, + EGLConfig* outConfig) { - ALOGI( "SurfaceFlinger's main thread ready to run. " - "Initializing graphics H/W..."); + EGLConfig config = NULL; + EGLint numConfigs = -1, n=0; + eglGetConfigs(dpy, NULL, 0, &numConfigs); + EGLConfig* const configs = new EGLConfig[numConfigs]; + eglChooseConfig(dpy, attrs, configs, numConfigs, &n); + for (int i=0 ; i<n ; i++) { + EGLint nativeVisualId = 0; + eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId); + if (nativeVisualId>0 && format == nativeVisualId) { + *outConfig = configs[i]; + delete [] configs; + return NO_ERROR; + } + } + delete [] configs; + return NAME_NOT_FOUND; +} - // we only support one display currently - int dpy = 0; +EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) { + // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if + // it is to be used with WIFI displays + EGLConfig config; + EGLint dummy; + status_t err; + EGLint attribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RECORDABLE_ANDROID, EGL_TRUE, + EGL_NONE + }; + err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); + if (err) { + // maybe we failed because of EGL_RECORDABLE_ANDROID + ALOGW("couldn't find an EGLConfig with EGL_RECORDABLE_ANDROID"); + attribs[2] = EGL_NONE; + err = selectConfigForPixelFormat(display, attribs, nativeVisualId, &config); + } + ALOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); + if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { + ALOGW_IF(dummy == EGL_SLOW_CONFIG, "EGL_SLOW_CONFIG selected!"); + } + return config; +} + +EGLContext SurfaceFlinger::createGLContext(EGLDisplay display, EGLConfig config) { + // Also create our EGLContext + EGLint contextAttributes[] = { +#ifdef EGL_IMG_context_priority +#ifdef HAS_CONTEXT_PRIORITY +#warning "using EGL_IMG_context_priority" + EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG, +#endif +#endif + EGL_NONE, EGL_NONE + }; + EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes); + ALOGE_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed"); + return ctxt; +} - { - // initialize the main display - // TODO: initialize all displays - DisplayHardware* const hw = new DisplayHardware(this, dpy); - mDisplayHardwares[0] = hw; +void SurfaceFlinger::initializeGL(EGLDisplay display, EGLSurface surface) { + EGLBoolean result = eglMakeCurrent(display, surface, surface, mEGLContext); + if (!result) { + ALOGE("Couldn't create a working GLES context. check logs. exiting..."); + exit(0); } - // create the shared control-block - mServerHeap = new MemoryHeapBase(4096, - MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); - ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); + GLExtensions& extensions(GLExtensions::getInstance()); + extensions.initWithGLStrings( + glGetString(GL_VENDOR), + glGetString(GL_RENDERER), + glGetString(GL_VERSION), + glGetString(GL_EXTENSIONS), + eglQueryString(display, EGL_VENDOR), + eglQueryString(display, EGL_VERSION), + eglQueryString(display, EGL_EXTENSIONS)); - mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); - ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); + EGLint w, h; + eglQuerySurface(display, surface, EGL_WIDTH, &w); + eglQuerySurface(display, surface, EGL_HEIGHT, &h); - new(mServerCblk) surface_flinger_cblk_t; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); - // initialize primary screen - // (other display should be initialized in the same manner, but - // asynchronously, as they could come and go. None of this is supported - // yet). - const DisplayHardware& hw(getDefaultDisplayHardware()); - const uint32_t w = hw.getWidth(); - const uint32_t h = hw.getHeight(); - const uint32_t f = hw.getFormat(); - hw.makeCurrent(); - - // initialize the shared control block - mServerCblk->connected |= 1<<dpy; - display_cblk_t* dcblk = mServerCblk->displays + dpy; - memset(dcblk, 0, sizeof(display_cblk_t)); - dcblk->w = w; // XXX: plane.getWidth(); - dcblk->h = h; // XXX: plane.getHeight(); - dcblk->format = f; - dcblk->orientation = ISurfaceComposer::eOrientationDefault; - dcblk->xdpi = hw.getDpiX(); - dcblk->ydpi = hw.getDpiY(); - dcblk->fps = hw.getRefreshRate(); - dcblk->density = hw.getDensity(); - - // Initialize OpenGL|ES glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); glEnableClientState(GL_VERTEX_ARRAY); @@ -258,6 +297,12 @@ status_t SurfaceFlinger::readyToRun() glDisable(GL_DITHER); glDisable(GL_CULL_FACE); + struct pack565 { + inline uint16_t operator() (int r, int g, int b) const { + return (r<<11)|(g<<5)|b; + } + } pack565; + const uint16_t g0 = pack565(0x0F,0x1F,0x0F); const uint16_t g1 = pack565(0x17,0x2f,0x17); const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; @@ -286,15 +331,77 @@ status_t SurfaceFlinger::readyToRun() // put the origin in the left-bottom corner glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h + // print some debugging info + EGLint r,g,b,a; + eglGetConfigAttrib(display, mEGLConfig, EGL_RED_SIZE, &r); + eglGetConfigAttrib(display, mEGLConfig, EGL_GREEN_SIZE, &g); + eglGetConfigAttrib(display, mEGLConfig, EGL_BLUE_SIZE, &b); + eglGetConfigAttrib(display, mEGLConfig, EGL_ALPHA_SIZE, &a); + ALOGI("EGL informations:"); + ALOGI("vendor : %s", extensions.getEglVendor()); + ALOGI("version : %s", extensions.getEglVersion()); + ALOGI("extensions: %s", extensions.getEglExtension()); + ALOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); + ALOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, mEGLConfig); + ALOGI("OpenGL ES informations:"); + ALOGI("vendor : %s", extensions.getVendor()); + ALOGI("renderer : %s", extensions.getRenderer()); + ALOGI("version : %s", extensions.getVersion()); + ALOGI("extensions: %s", extensions.getExtension()); + ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); + ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); +} + +surface_flinger_cblk_t* SurfaceFlinger::getControlBlock() const { + return mServerCblk; +} + +status_t SurfaceFlinger::readyToRun() +{ + ALOGI( "SurfaceFlinger's main thread ready to run. " + "Initializing graphics H/W..."); + + // create the shared control-block + mServerHeap = new MemoryHeapBase(4096, + MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); + ALOGE_IF(mServerHeap==0, "can't create shared memory dealer"); + mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); + ALOGE_IF(mServerCblk==0, "can't get to shared control block's address"); + new(mServerCblk) surface_flinger_cblk_t; + + + // initialize EGL + EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + eglInitialize(display, NULL, NULL); + + // Initialize the main display + // create native window to main display + sp<FramebufferSurface> anw = FramebufferSurface::create(); + ANativeWindow* const window = anw.get(); + if (!window) { + ALOGE("Display subsystem failed to initialize. check logs. exiting..."); + exit(0); + } + + // initialize the config and context + int format; + window->query(window, NATIVE_WINDOW_FORMAT, &format); + mEGLConfig = selectEGLConfig(display, format); + mEGLContext = createGLContext(display, mEGLConfig); + + // initialize our main display hardware + DisplayHardware* const hw = new DisplayHardware(this, 0, anw, mEGLConfig); + mDisplayHardwares[0] = hw; + + // initialize OpenGL ES + EGLSurface surface = hw->getEGLSurface(); + initializeGL(display, surface); // start the EventThread mEventThread = new EventThread(this); mEventQueue.setEventThread(mEventThread); - /* - * We're now ready to accept clients... - */ - + // We're now ready to accept clients... mReadyToRunBarrier.open(); // start boot animation @@ -309,6 +416,15 @@ void SurfaceFlinger::startBootAnim() { property_set("ctl.start", "bootanim"); } +uint32_t SurfaceFlinger::getMaxTextureSize() const { + return mMaxTextureSize; +} + +uint32_t SurfaceFlinger::getMaxViewportDims() const { + return mMaxViewportDims[0] < mMaxViewportDims[1] ? + mMaxViewportDims[0] : mMaxViewportDims[1]; +} + // ---------------------------------------------------------------------------- bool SurfaceFlinger::authenticateSurfaceTexture( @@ -367,7 +483,7 @@ void SurfaceFlinger::connectDisplay(const sp<ISurfaceTexture> display) { if (display != NULL) { stc = new SurfaceTextureClient(display); result = eglCreateWindowSurface(hw.getEGLDisplay(), - hw.getEGLConfig(), (EGLNativeWindowType)stc.get(), NULL); + mEGLConfig, (EGLNativeWindowType)stc.get(), NULL); ALOGE_IF(result == EGL_NO_SURFACE, "eglCreateWindowSurface failed (ISurfaceTexture=%p)", display.get()); @@ -465,6 +581,40 @@ void SurfaceFlinger::handleMessageInvalidate() { void SurfaceFlinger::handleMessageRefresh() { handleRefresh(); + if (mVisibleRegionsDirty) { + Region opaqueRegion; + Region dirtyRegion; + const LayerVector& currentLayers(mDrawingState.layersSortedByZ); + computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion); + mDirtyRegion.orSelf(dirtyRegion); + + /* + * rebuild the visible layer list per screen + */ + + // TODO: iterate through all displays + DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0))); + + Vector< sp<LayerBase> > layersSortedByZ; + const size_t count = currentLayers.size(); + for (size_t i=0 ; i<count ; i++) { + if (!currentLayers[i]->visibleRegion.isEmpty()) { + // TODO: also check that this layer is associated to this display + layersSortedByZ.add(currentLayers[i]); + } + } + hw.setVisibleLayersSortedByZ(layersSortedByZ); + + + // 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(); + } + + // XXX: dirtyRegion should be per screen, we should check all of them if (mDirtyRegion.isEmpty()) { return; @@ -515,7 +665,8 @@ void SurfaceFlinger::handleMessageRefresh() { glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); + + const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() ); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); @@ -546,7 +697,8 @@ void SurfaceFlinger::postFramebuffer() const DisplayHardware& hw(getDefaultDisplayHardware()); HWComposer& hwc(hw.getHwComposer()); - size_t numLayers = mVisibleLayersSortedByZ.size(); + const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); + size_t numLayers = layers.size(); const nsecs_t now = systemTime(); mDebugInSwapBuffers = now; @@ -555,7 +707,7 @@ void SurfaceFlinger::postFramebuffer() const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { if (cur->getCompositionType() == HWC_OVERLAY) { - mVisibleLayersSortedByZ[i]->setAcquireFence(*cur); + layers[i]->setAcquireFence(*cur); } else { cur->setAcquireFenceFd(-1); } @@ -568,11 +720,11 @@ void SurfaceFlinger::postFramebuffer() HWComposer::LayerListIterator cur = hwc.begin(); const HWComposer::LayerListIterator end = hwc.end(); for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) { - mVisibleLayersSortedByZ[i]->onLayerDisplayed(&*cur); + layers[i]->onLayerDisplayed(&*cur); } } else { for (size_t i = 0; i < numLayers; i++) { - mVisibleLayersSortedByZ[i]->onLayerDisplayed(NULL); + layers[i]->onLayerDisplayed(NULL); } } @@ -713,7 +865,7 @@ void SurfaceFlinger::computeVisibleRegions( Region aboveCoveredLayers; Region dirty; - bool secureFrameBuffer = false; + dirtyRegion.clear(); size_t i = currentLayers.size(); while (i--) { @@ -823,14 +975,8 @@ void SurfaceFlinger::computeVisibleRegions( // Store the visible region is screen space layer->setVisibleRegion(visibleRegion); layer->setCoveredRegion(coveredRegion); - - // If a secure layer is partially visible, lock-down the screen! - if (layer->isSecure() && !visibleRegion.isEmpty()) { - secureFrameBuffer = true; - } } - mSecureFrameBuffer = secureFrameBuffer; opaqueRegion = aboveOpaqueLayers; } @@ -849,30 +995,7 @@ Region SurfaceFlinger::handlePageFlip() dirtyRegion.orSelf( layer->latchBuffer(visibleRegions) ); } - if (visibleRegions || mVisibleRegionsDirty) { - Region opaqueRegion; - computeVisibleRegions(currentLayers, dirtyRegion, opaqueRegion); - - /* - * 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]); - } - - // 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(); - } + mVisibleRegionsDirty |= visibleRegions; return dirtyRegion; } @@ -904,7 +1027,7 @@ void SurfaceFlinger::handleWorkList(const DisplayHardware& hw) mHwWorkListDirty = false; HWComposer& hwc(hw.getHwComposer()); if (hwc.initCheck() == NO_ERROR) { - const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); + const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ()); const size_t count = currentLayers.size(); hwc.createWorkList(count); @@ -971,7 +1094,7 @@ void SurfaceFlinger::setupHardwareComposer(const DisplayHardware& hw) return; } - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); + const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); size_t count = layers.size(); ALOGE_IF(hwc.getNumLayers() != count, @@ -1025,25 +1148,29 @@ void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& di * and then, render the layers targeted at the framebuffer */ - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); + const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); const size_t count = layers.size(); const Transform& tr = hw.getTransform(); - for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { + for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); const Region clip(dirty.intersect(tr.transform(layer->visibleRegion))); if (!clip.isEmpty()) { - if (cur->getCompositionType() == HWC_OVERLAY) { + if (cur != end && cur->getCompositionType() == HWC_OVERLAY) { if (i && (cur->getHints() & HWC_HINT_CLEAR_FB) && layer->isOpaque()) { // never clear the very first layer since we're // guaranteed the FB is already cleared layer->clearWithOpenGL(hw, clip); } + ++cur; continue; } // render the layer layer->draw(hw, clip); } + if (cur != end) { + ++cur; + } } } } @@ -1741,7 +1868,7 @@ void SurfaceFlinger::dumpAllLocked( hwc.initCheck()==NO_ERROR ? "present" : "not present", (mDebugDisableHWC || mDebugRegion) ? "disabled" : "enabled"); result.append(buffer); - hwc.dump(result, buffer, SIZE, mVisibleLayersSortedByZ); + hwc.dump(result, buffer, SIZE, hw.getVisibleLayersSortedByZ()); /* * Dump gralloc state @@ -1931,7 +2058,7 @@ status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy, glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); + const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ()); const size_t count = layers.size(); for (size_t i=0 ; i<count ; ++i) { const sp<LayerBase>& layer(layers[i]); @@ -2428,19 +2555,27 @@ status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy, status_t result = PERMISSION_DENIED; // only one display supported for now - if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) + if (CC_UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT)) { return BAD_VALUE; + } - if (!GLExtensions::getInstance().haveFramebufferObject()) + if (!GLExtensions::getInstance().haveFramebufferObject()) { return INVALID_OPERATION; + } // get screen geometry const DisplayHardware& hw(getDisplayHardware(dpy)); const uint32_t hw_w = hw.getWidth(); const uint32_t hw_h = hw.getHeight(); - if ((sw > hw_w) || (sh > hw_h)) + // if we have secure windows on this display, never allow the screen capture + if (hw.getSecureLayerVisible()) { + return PERMISSION_DENIED; + } + + if ((sw > hw_w) || (sh > hw_h)) { return BAD_VALUE; + } sw = (!sw) ? hw_w : sw; sh = (!sh) ? hw_h : sh; @@ -2579,14 +2714,8 @@ status_t SurfaceFlinger::captureScreen(DisplayID dpy, } virtual bool handler() { Mutex::Autolock _l(flinger->mStateLock); - - // if we have secure windows, never allow the screen capture - if (flinger->mSecureFrameBuffer) - return true; - result = flinger->captureScreenImplLocked(dpy, heap, w, h, f, sw, sh, minLayerZ, maxLayerZ); - return true; } }; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 91cc6a5..4af31fb 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -148,6 +148,8 @@ public: GLuint getProtectedTexName() const { return mProtectedTexName; } + surface_flinger_cblk_t* getControlBlock() const; + class MessageDestroyGLTexture : public MessageBase { GLuint texture; @@ -294,6 +296,18 @@ private: void debugFlashRegions(const DisplayHardware& hw); void drawWormhole() const; + uint32_t getMaxTextureSize() const; + uint32_t getMaxViewportDims() const; + + static status_t selectConfigForPixelFormat( + EGLDisplay dpy, + EGLint const* attrs, + PixelFormat format, + EGLConfig* outConfig); + static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId); + static EGLContext createGLContext(EGLDisplay disp, EGLConfig config); + void initializeGL(EGLDisplay display, EGLSurface surface); + void startBootAnim(); void listLayersLocked(const Vector<String16>& args, size_t& index, @@ -331,6 +345,11 @@ private: GLuint mProtectedTexName; nsecs_t mBootTime; sp<EventThread> mEventThread; + GLint mMaxViewportDims[2]; + GLint mMaxTextureSize; + EGLContext mEGLContext; + EGLConfig mEGLConfig; + // Can only accessed from the main thread, these members // don't need synchronization @@ -342,7 +361,6 @@ private: bool mVisibleRegionsDirty; bool mHwWorkListDirty; int32_t mElectronBeamAnimationMode; - Vector< sp<LayerBase> > mVisibleLayersSortedByZ; // don't use a lock for these, we don't care @@ -364,9 +382,6 @@ private: mutable Mutex mDestroyedLayerLock; Vector<LayerBase const *> mDestroyedLayers; - // only written in the main thread, only read in other threads - volatile int32_t mSecureFrameBuffer; - EGLSurface getExternalDisplaySurface() const; sp<SurfaceTextureClient> mExternalDisplayNativeWindow; |