summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/HardwareRenderer.java15
-rw-r--r--core/java/android/view/ViewRootImpl.java23
-rw-r--r--libs/hwui/DeferredDisplayList.h4
-rw-r--r--libs/hwui/FontRenderer.cpp35
-rw-r--r--libs/hwui/Layer.cpp5
-rw-r--r--libs/hwui/Layer.h7
-rw-r--r--libs/hwui/LayerRenderer.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp10
-rw-r--r--libs/hwui/font/CacheTexture.cpp3
-rw-r--r--libs/hwui/font/CacheTexture.h2
-rw-r--r--tools/aapt/Command.cpp8
11 files changed, 68 insertions, 46 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 7918823..8055077 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -451,10 +451,8 @@ public abstract class HardwareRenderer {
* @param attachInfo AttachInfo tied to the specified view.
* @param callbacks Callbacks invoked when drawing happens.
* @param dirty The dirty rectangle to update, can be null.
- *
- * @return true if the dirty rect was ignored, false otherwise
*/
- abstract boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ abstract void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
Rect dirty);
/**
@@ -992,11 +990,7 @@ public abstract class HardwareRenderer {
mCanvas = createCanvas();
mCanvas.setName(mName);
}
- if (mCanvas != null) {
- setEnabled(true);
- } else {
- Log.w(LOG_TAG, "Hardware accelerated Canvas could not be created");
- }
+ setEnabled(true);
}
return mCanvas != null;
@@ -1340,7 +1334,7 @@ public abstract class HardwareRenderer {
}
@Override
- boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
+ void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
Rect dirty) {
if (canDraw()) {
if (!hasDirtyRegions()) {
@@ -1401,11 +1395,8 @@ public abstract class HardwareRenderer {
}
attachInfo.mIgnoreDirtyState = false;
- return dirty == null;
}
}
-
- return false;
}
private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 9387624..efa8a9e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -197,7 +197,6 @@ public final class ViewRootImpl implements ViewParent,
int mHeight;
Rect mDirty;
final Rect mCurrentDirty = new Rect();
- final Rect mPreviousDirty = new Rect();
boolean mIsAnimating;
CompatibilityInfo.Translator mTranslator;
@@ -767,10 +766,11 @@ public final class ViewRootImpl implements ViewParent,
final boolean translucent = attrs.format != PixelFormat.OPAQUE;
mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);
- mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
- mAttachInfo.mHardwareAccelerated = mAttachInfo.mHardwareAccelerationRequested
- = mAttachInfo.mHardwareRenderer != null;
-
+ if (mAttachInfo.mHardwareRenderer != null) {
+ mAttachInfo.mHardwareRenderer.setName(attrs.getTitle().toString());
+ mAttachInfo.mHardwareAccelerated =
+ mAttachInfo.mHardwareAccelerationRequested = true;
+ }
} 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
@@ -2387,14 +2387,10 @@ public final class ViewRootImpl implements ViewParent,
mResizeAlpha = resizeAlpha;
mCurrentDirty.set(dirty);
- mCurrentDirty.union(mPreviousDirty);
- mPreviousDirty.set(dirty);
dirty.setEmpty();
- if (attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
- animating ? null : mCurrentDirty)) {
- mPreviousDirty.set(0, 0, mWidth, mHeight);
- }
+ attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,
+ animating ? null : mCurrentDirty);
} else {
// If we get here with a disabled & requested hardware renderer, something went
// wrong (an invalidate posted right before we destroyed the hardware surface
@@ -2449,6 +2445,8 @@ public final class ViewRootImpl implements ViewParent,
canvas = mSurface.lockCanvas(dirty);
+ // The dirty rectangle can be modified by Surface.lockCanvas()
+ //noinspection ConstantConditions
if (left != dirty.left || top != dirty.top || right != dirty.right ||
bottom != dirty.bottom) {
attachInfo.mIgnoreDirtyState = true;
@@ -3099,8 +3097,7 @@ public final class ViewRootImpl implements ViewParent,
boolean inTouchMode = msg.arg2 != 0;
ensureTouchModeLocally(inTouchMode);
- if (mAttachInfo.mHardwareRenderer != null &&
- mSurface != null && mSurface.isValid()) {
+ if (mAttachInfo.mHardwareRenderer != null && mSurface.isValid()){
mFullRedrawNeeded = true;
try {
mAttachInfo.mHardwareRenderer.initializeIfNeeded(
diff --git a/libs/hwui/DeferredDisplayList.h b/libs/hwui/DeferredDisplayList.h
index 3e450da..653f315 100644
--- a/libs/hwui/DeferredDisplayList.h
+++ b/libs/hwui/DeferredDisplayList.h
@@ -52,8 +52,6 @@ public:
kOpBatch_Count, // Add other batch ids before this
};
- void clear();
-
bool isEmpty() { return mBatches.isEmpty(); }
/**
@@ -80,6 +78,8 @@ private:
*/
void resetBatchingState();
+ void clear();
+
void storeStateOpBarrier(OpenGLRenderer& renderer, StateOp* op);
void storeRestoreToCountBarrier(OpenGLRenderer& renderer, StateOp* op, int newSaveCount);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 26c7e5d..44dc731 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -31,6 +31,7 @@
#include "Caches.h"
#include "Debug.h"
+#include "Extensions.h"
#include "FontRenderer.h"
#include "Rect.h"
@@ -375,34 +376,60 @@ void FontRenderer::checkTextureUpdate() {
Caches& caches = Caches::getInstance();
GLuint lastTextureId = 0;
+
+ // OpenGL ES 3.0+ lets us specify the row length for unpack operations such
+ // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
+ // With OpenGL ES 2.0 we have to upload entire stripes instead.
+ const bool hasUnpackRowLength = Extensions::getInstance().getMajorGlVersion() >= 3;
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
// Iterate over all the cache textures and see which ones need to be updated
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
CacheTexture* cacheTexture = mCacheTextures[i];
if (cacheTexture->isDirty() && cacheTexture->getTexture()) {
- // Can't copy inner rect; glTexSubimage expects pointer to deal with entire buffer
- // of data. So expand the dirty rect to the encompassing horizontal stripe.
const Rect* dirtyRect = cacheTexture->getDirtyRect();
- uint32_t x = 0;
+ uint32_t x = hasUnpackRowLength ? dirtyRect->left : 0;
uint32_t y = dirtyRect->top;
uint32_t width = cacheTexture->getWidth();
uint32_t height = dirtyRect->getHeight();
- void* textureData = cacheTexture->getTexture() + y * width;
+ void* textureData = cacheTexture->getTexture() + y * width + x;
if (cacheTexture->getTextureId() != lastTextureId) {
lastTextureId = cacheTexture->getTextureId();
caches.activeTexture(0);
glBindTexture(GL_TEXTURE_2D, lastTextureId);
+
+ // The unpack row length only needs to be specified when a new
+ // texture is bound
+ if (hasUnpackRowLength) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
+ }
+ }
+
+ // If we can upload a sub-rectangle, use the dirty rect width
+ // instead of the width of the entire texture
+ if (hasUnpackRowLength) {
+ width = dirtyRect->getWidth();
}
+
#if DEBUG_FONT_RENDERER
ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
i, x, y, width, height);
#endif
+
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
+
cacheTexture->setDirty(false);
}
}
+ // Reset to default unpack row length to avoid affecting texture
+ // uploads in other parts of the renderer
+ if (hasUnpackRowLength) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ }
+
mUploadTexture = false;
}
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 63bb73f..a718294 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -90,7 +90,7 @@ bool Layer::resize(const uint32_t width, const uint32_t height) {
if (fbo) {
Caches::getInstance().activeTexture(0);
bindTexture();
- allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+ allocateTexture();
if (glGetError() != GL_NO_ERROR) {
setSize(oldWidth, oldHeight);
@@ -167,7 +167,6 @@ void Layer::defer() {
displayList->defer(deferredState, 0);
deferredUpdateScheduled = false;
- displayList = NULL;
}
void Layer::flush() {
@@ -182,7 +181,7 @@ void Layer::flush() {
renderer = NULL;
dirtyRect.setEmpty();
- deferredList->clear();
+ displayList = NULL;
}
}
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 27e0cf1..715dfa4 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -255,13 +255,14 @@ struct Layer {
texture.id = 0;
}
- inline void allocateTexture(GLenum format, GLenum storage) {
+ inline void allocateTexture() {
#if DEBUG_LAYERS
ALOGD(" Allocate layer: %dx%d", getWidth(), getHeight());
#endif
if (texture.id) {
- glTexImage2D(renderTarget, 0, format, getWidth(), getHeight(), 0,
- format, storage, NULL);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glTexImage2D(renderTarget, 0, GL_RGBA, getWidth(), getHeight(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
}
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 8451048..3e55fff 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -256,7 +256,7 @@ Layer* LayerRenderer::createLayer(uint32_t width, uint32_t height, bool isOpaque
// Initialize the texture if needed
if (layer->isEmpty()) {
layer->setEmpty(false);
- layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+ layer->allocateTexture();
// This should only happen if we run out of memory
if (glGetError() != GL_NO_ERROR) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 1138998..3730017 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -571,8 +571,8 @@ void OpenGLRenderer::updateLayers() {
startMark("Defer Layer Updates");
}
- // Note: it is very important to update the layers in reverse order
- for (int i = count - 1; i >= 0; i--) {
+ // Note: it is very important to update the layers in order
+ for (int i = 0; i < count; i++) {
Layer* layer = mLayerUpdates.itemAt(i);
updateLayer(layer, false);
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
@@ -594,8 +594,8 @@ void OpenGLRenderer::flushLayers() {
startMark("Apply Layer Updates");
char layerName[12];
- // Note: it is very important to update the layers in reverse order
- for (int i = count - 1; i >= 0; i--) {
+ // Note: it is very important to update the layers in order
+ for (int i = 0; i < count; i++) {
sprintf(layerName, "Layer #%d", i);
startMark(layerName);
@@ -922,7 +922,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui
// Initialize the texture if needed
if (layer->isEmpty()) {
- layer->allocateTexture(GL_RGBA, GL_UNSIGNED_BYTE);
+ layer->allocateTexture();
layer->setEmpty(false);
}
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
index 1096642..577f463 100644
--- a/libs/hwui/font/CacheTexture.cpp
+++ b/libs/hwui/font/CacheTexture.cpp
@@ -15,10 +15,9 @@
*/
#include <SkGlyph.h>
-#include <utils/Log.h>
-#include "Debug.h"
#include "CacheTexture.h"
+#include "../Debug.h"
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
index 5742941..e7fb474 100644
--- a/libs/hwui/font/CacheTexture.h
+++ b/libs/hwui/font/CacheTexture.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_HWUI_CACHE_TEXTURE_H
#define ANDROID_HWUI_CACHE_TEXTURE_H
-#include <GLES2/gl2.h>
+#include <GLES3/gl3.h>
#include <SkScalerContext.h>
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 84f5a5c..cadac02 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -592,6 +592,10 @@ int doDump(Bundle* bundle)
goto bail;
}
printf("uses-permission: %s\n", name.string());
+ int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
+ if (!req) {
+ printf("optional-permission: %s\n", name.string());
+ }
}
}
} else if (strcmp("badging", option) == 0) {
@@ -1033,6 +1037,10 @@ int doDump(Bundle* bundle)
hasWriteCallLogPermission = true;
}
printf("uses-permission:'%s'\n", name.string());
+ int req = getIntegerAttribute(tree, REQUIRED_ATTR, NULL, 1);
+ if (!req) {
+ printf("optional-permission:'%s'\n", name.string());
+ }
} else {
fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
error.string());