summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRomain Guy <romainguy@google.com>2012-02-01 16:10:55 -0800
committerRomain Guy <romainguy@google.com>2012-02-01 16:10:55 -0800
commit211370fd943cf26905001b38b8b1791851b26adc (patch)
tree03db29f15516e381b8f4553a87756c03c64d028a
parenta403a2e0f0d55a709821a6310de849176dc9b426 (diff)
downloadframeworks_base-211370fd943cf26905001b38b8b1791851b26adc.zip
frameworks_base-211370fd943cf26905001b38b8b1791851b26adc.tar.gz
frameworks_base-211370fd943cf26905001b38b8b1791851b26adc.tar.bz2
Add optional metadata to initiliaze the render threat.
The render threat is likely to break your application if you initiate it. As such it must be explicitely requested using the following meta-data tag in your manifest's application tag: <meta-data android:name="android.graphics.renderThread" android:value="true" /> Change-Id: Ibf0a48af2a0d091562bf6907eac970e3d1d601c4
-rw-r--r--core/java/android/view/ViewRootImpl.java66
-rw-r--r--core/java/android/view/WindowManagerImpl.java2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp56
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml2
4 files changed, 80 insertions, 46 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2ef843b..dd61717 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -23,6 +23,7 @@ import android.content.ClipDescription;
import android.content.ComponentCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -81,7 +82,6 @@ import com.android.internal.view.RootViewSurfaceTaker;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -139,6 +139,10 @@ public final class ViewRootImpl extends Handler implements ViewParent,
static final ArrayList<ComponentCallbacks> sConfigCallbacks
= new ArrayList<ComponentCallbacks>();
+ private static boolean sUseRenderThread = false;
+ private static boolean sRenderThreadQueried = false;
+ private static final Object[] sRenderThreadQueryLock = new Object[0];
+
long mLastTrackballTime = 0;
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
@@ -378,6 +382,31 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mChoreographer = Choreographer.getInstance();
}
+ /**
+ * @return True if the application requests the use of a separate render thread,
+ * false otherwise
+ */
+ private static boolean isRenderThreadRequested(Context context) {
+ synchronized (sRenderThreadQueryLock) {
+ if (!sRenderThreadQueried) {
+ final PackageManager packageManager = context.getPackageManager();
+ final String packageName = context.getApplicationInfo().packageName;
+ try {
+ ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
+ PackageManager.GET_META_DATA);
+ if (applicationInfo.metaData != null) {
+ sUseRenderThread = applicationInfo.metaData.getBoolean(
+ "android.graphics.renderThread", false);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ } finally {
+ sRenderThreadQueried = true;
+ }
+ }
+ return sUseRenderThread;
+ }
+ }
+
public static void addFirstDrawHandler(Runnable callback) {
synchronized (sFirstDrawHandlers) {
if (!sFirstDrawComplete) {
@@ -448,7 +477,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
// If the application owns the surface, don't enable hardware acceleration
if (mSurfaceHolder == null) {
- enableHardwareAcceleration(attrs);
+ enableHardwareAcceleration(mView.getContext(), attrs);
}
boolean restore = false;
@@ -608,7 +637,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
}
- private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
+ private void enableHardwareAcceleration(Context context, WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
@@ -641,20 +670,27 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (!HardwareRenderer.sRendererDisabled || (HardwareRenderer.sSystemRendererDisabled
&& forceHwAccelerated)) {
// Don't enable hardware acceleration when we're not on the main thread
- if (!HardwareRenderer.sSystemRendererDisabled
- && Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ if (!HardwareRenderer.sSystemRendererDisabled &&
+ Looper.getMainLooper() != Looper.myLooper()) {
+ Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ "acceleration outside of the main thread, aborting");
return;
}
- final boolean translucent = attrs.format != PixelFormat.OPAQUE;
+ boolean renderThread = isRenderThreadRequested(context);
+ if (renderThread) {
+ Log.i(HardwareRenderer.LOG_TAG, "Render threat initiated");
+ }
+
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
- }
+ }
+
+ final boolean translucent = attrs.format != PixelFormat.OPAQUE;
mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
= mAttachInfo.mHardwareRenderer != null;
+
} else if (fakeHwAccelerated) {
// The window had wanted to use hardware acceleration, but this
// is not allowed in its process. By setting this flag, it can
@@ -3441,11 +3477,11 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (args.localChanges != 0) {
if (mAttachInfo != null) {
mAttachInfo.mSystemUiVisibility =
- (mAttachInfo.mSystemUiVisibility&~args.localChanges)
- | (args.localValue&args.localChanges);
+ (mAttachInfo.mSystemUiVisibility & ~args.localChanges) |
+ (args.localValue & args.localChanges);
+ mAttachInfo.mRecomputeGlobalAttributes = true;
}
mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
- mAttachInfo.mRecomputeGlobalAttributes = true;
scheduleTraversals();
}
mView.dispatchSystemUiVisibilityChanged(args.globalVisibility);
@@ -3588,7 +3624,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mView.debug();
}
- public void dumpGfxInfo(PrintWriter pw, int[] info) {
+ public void dumpGfxInfo(int[] info) {
if (mView != null) {
getGfxInfo(mView, info);
} else {
@@ -3700,7 +3736,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
* Represents a pending input event that is waiting in a queue.
*
* Input events are processed in serial order by the timestamp specified by
- * {@link InputEvent#getEventTime()}. In general, the input dispatcher delivers
+ * {@link InputEvent#getEventTimeNano()}. In general, the input dispatcher delivers
* one input event to the application at a time and waits for the application
* to finish handling it before delivering the next one.
*
@@ -3709,7 +3745,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
* needing a queue on the application's side.
*/
private static final class QueuedInputEvent {
- public static final int FLAG_DELIVER_POST_IME = 1 << 0;
+ public static final int FLAG_DELIVER_POST_IME = 1;
public QueuedInputEvent mNext;
@@ -4782,7 +4818,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mPool.release(args);
List<AccessibilityNodeInfo> infos = null;
try {
- View target = null;
+ View target;
if (accessibilityViewId != View.NO_ID) {
target = findViewByAccessibilityId(accessibilityViewId);
} else {
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index d711337..6bdc4e8 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -490,7 +490,7 @@ public class WindowManagerImpl implements WindowManager {
for (int i = 0; i < count; i++) {
ViewRootImpl root = mRoots[i];
- root.dumpGfxInfo(pw, info);
+ root.dumpGfxInfo(info);
String name = root.getClass().getName() + '@' +
Integer.toHexString(hashCode());
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index bd213d5..afae70f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -754,7 +754,7 @@ void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
// TODO: See LayerRenderer.cpp::generateMesh() for important
// information about this implementation
- if (!layer->region.isEmpty()) {
+ if (CC_LIKELY(!layer->region.isEmpty())) {
size_t count;
const android::Rect* rects = layer->region.getArray(&count);
@@ -1398,7 +1398,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint
if (!texture) return;
const AutoTexture autoCleanup(texture);
- if (bitmap->getConfig() == SkBitmap::kA8_Config) {
+ if (CC_UNLIKELY(bitmap->getConfig() == SkBitmap::kA8_Config)) {
drawAlphaBitmap(texture, left, top, paint);
} else {
drawTextureRect(left, top, right, bottom, texture, paint);
@@ -1454,9 +1454,9 @@ void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHei
float bottom = FLT_MIN;
#if RENDER_LAYERS_AS_REGIONS
- bool hasActiveLayer = hasLayer();
+ const bool hasActiveLayer = hasLayer();
#else
- bool hasActiveLayer = false;
+ const bool hasActiveLayer = false;
#endif
// TODO: Support the colors array
@@ -1541,7 +1541,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
texture->setWrap(GL_CLAMP_TO_EDGE, true);
- if (mSnapshot->transform->isPureTranslate()) {
+ if (CC_LIKELY(mSnapshot->transform->isPureTranslate())) {
const float x = (int) floorf(dstLeft + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(dstTop + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -1587,7 +1587,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
const Patch* mesh = mCaches.patchCache.get(bitmap->width(), bitmap->height(),
right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
- if (mesh && mesh->verticesCount > 0) {
+ if (CC_LIKELY(mesh && mesh->verticesCount > 0)) {
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
#if RENDER_LAYERS_AS_REGIONS
// Mark the current layer dirty where we are going to draw the patch
@@ -1597,7 +1597,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
const size_t count = mesh->quads.size();
for (size_t i = 0; i < count; i++) {
const Rect& bounds = mesh->quads.itemAt(i);
- if (pureTranslate) {
+ if (CC_LIKELY(pureTranslate)) {
const float x = (int) floorf(bounds.left + offsetX + 0.5f);
const float y = (int) floorf(bounds.top + offsetY + 0.5f);
dirtyLayer(x, y, x + bounds.getWidth(), y + bounds.getHeight());
@@ -1609,7 +1609,7 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int
}
#endif
- if (pureTranslate) {
+ if (CC_LIKELY(pureTranslate)) {
const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -1637,7 +1637,7 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
float inverseScaleX = 1.0f;
float inverseScaleY = 1.0f;
// The quad that we use needs to account for scaling.
- if (!mSnapshot->transform->isPureTranslate()) {
+ if (CC_UNLIKELY(!mSnapshot->transform->isPureTranslate())) {
Matrix4 *mat = mSnapshot->transform;
float m00 = mat->data[Matrix4::kScaleX];
float m01 = mat->data[Matrix4::kSkewY];
@@ -1743,7 +1743,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
// The quad that we use for AA and hairlines needs to account for scaling. For hairlines
// the line on the screen should always be one pixel wide regardless of scale. For
// AA lines, we only want one pixel of translucent boundary around the quad.
- if (!mSnapshot->transform->isPureTranslate()) {
+ if (CC_UNLIKELY(!mSnapshot->transform->isPureTranslate())) {
Matrix4 *mat = mSnapshot->transform;
float m00 = mat->data[Matrix4::kScaleX];
float m01 = mat->data[Matrix4::kSkewY];
@@ -1751,8 +1751,8 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
float m10 = mat->data[Matrix4::kSkewX];
float m11 = mat->data[Matrix4::kScaleX];
float m12 = mat->data[6];
- float scaleX = sqrt(m00*m00 + m01*m01);
- float scaleY = sqrt(m10*m10 + m11*m11);
+ float scaleX = sqrtf(m00 * m00 + m01 * m01);
+ float scaleY = sqrtf(m10 * m10 + m11 * m11);
inverseScaleX = (scaleX != 0) ? (inverseScaleX / scaleX) : 0;
inverseScaleY = (scaleY != 0) ? (inverseScaleY / scaleY) : 0;
if (inverseScaleX != 1.0f || inverseScaleY != 1.0f) {
@@ -1770,11 +1770,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
setupDrawColor(paint->getColor(), alpha);
setupDrawColorFilter();
setupDrawShader();
- if (isAA) {
- setupDrawBlending(true, mode);
- } else {
- setupDrawBlending(mode);
- }
+ setupDrawBlending(isAA, mode);
setupDrawProgram();
setupDrawModelViewIdentity(true);
setupDrawColorUniforms();
@@ -1792,7 +1788,7 @@ void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
Vertex* vertices = &lines[0];
AAVertex wLines[verticesCount];
AAVertex* aaVertices = &wLines[0];
- if (!isAA) {
+ if (CC_UNLIKELY(!isAA)) {
setupDrawVertices(vertices);
} else {
void* widthCoords = ((GLbyte*) aaVertices) + gVertexAAWidthOffset;
@@ -2152,9 +2148,9 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count,
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
#if RENDER_LAYERS_AS_REGIONS
- bool hasActiveLayer = hasLayer();
+ const bool hasActiveLayer = hasLayer();
#else
- bool hasActiveLayer = false;
+ const bool hasActiveLayer = false;
#endif
if (fontRenderer.renderPosText(paint, clip, text, 0, bytesCount, count, x, y,
@@ -2201,7 +2197,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
const float oldX = x;
const float oldY = y;
const bool pureTranslate = mSnapshot->transform->isPureTranslate();
- if (pureTranslate) {
+ if (CC_LIKELY(pureTranslate)) {
x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
}
@@ -2218,7 +2214,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
- if (mHasShadow) {
+ if (CC_UNLIKELY(mHasShadow)) {
mCaches.activeTexture(0);
mCaches.dropShadowCache.setFontRenderer(fontRenderer);
@@ -2277,9 +2273,9 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
#if RENDER_LAYERS_AS_REGIONS
- bool hasActiveLayer = hasLayer();
+ const bool hasActiveLayer = hasLayer();
#else
- bool hasActiveLayer = false;
+ const bool hasActiveLayer = false;
#endif
if (fontRenderer.renderText(paint, clip, text, 0, bytesCount, count, x, y,
@@ -2326,7 +2322,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
layer->setAlpha(alpha, mode);
#if RENDER_LAYERS_AS_REGIONS
- if (!layer->region.isEmpty()) {
+ if (CC_LIKELY(!layer->region.isEmpty())) {
if (layer->region.isRect()) {
composeLayerRect(layer, layer->regionRect);
} else if (layer->mesh) {
@@ -2342,7 +2338,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
setupDrawTexture(layer->getTexture());
- if (mSnapshot->transform->isPureTranslate()) {
+ if (CC_LIKELY(mSnapshot->transform->isPureTranslate())) {
x = (int) floorf(x + mSnapshot->transform->getTranslateX() + 0.5f);
y = (int) floorf(y + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -2502,7 +2498,7 @@ void OpenGLRenderer::drawTextDecorations(const char* text, int bytesCount, float
break;
}
- if (underlineWidth > 0.0f) {
+ if (CC_LIKELY(underlineWidth > 0.0f)) {
const float textSize = paintCopy.getTextSize();
const float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
@@ -2571,7 +2567,7 @@ void OpenGLRenderer::drawTextureRect(float left, float top, float right, float b
texture->setWrap(GL_CLAMP_TO_EDGE, true);
- if (mSnapshot->transform->isPureTranslate()) {
+ if (CC_LIKELY(mSnapshot->transform->isPureTranslate())) {
const float x = (int) floorf(left + mSnapshot->transform->getTranslateX() + 0.5f);
const float y = (int) floorf(top + mSnapshot->transform->getTranslateY() + 0.5f);
@@ -2631,8 +2627,8 @@ void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode,
// the blending, turn blending off here
// If the blend mode cannot be implemented using shaders, fall
// back to the default SrcOver blend mode instead
- if (mode > SkXfermode::kScreen_Mode) {
- if (mCaches.extensions.hasFramebufferFetch()) {
+ if CC_UNLIKELY((mode > SkXfermode::kScreen_Mode)) {
+ if (CC_UNLIKELY(mCaches.extensions.hasFramebufferFetch())) {
description.framebufferMode = mode;
description.swapSrcDst = swapSrcDst;
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 5bbcce3..643cb8d 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -30,6 +30,8 @@
android:label="HwUi"
android:hardwareAccelerated="true">
+ <meta-data android:name="android.graphics.renderThread" android:value="true" />
+
<activity
android:name="PaintDrawFilterActivity"
android:label="_DrawFilter">