Merge "Add plumbing for volume mute key."
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 007e7b9..f80fbd8 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -129,6 +129,7 @@
private long[] mVibePattern;
private int mAspect;
+ private final Matrix mArrowMatrix = new Matrix();
/**
* Represents a cell in the 3 X 3 matrix of the unlock pattern view.
@@ -923,7 +924,6 @@
// This assumes that the arrow image is drawn at 12:00 with it's top edge
// coincident with the circle bitmap's top edge.
Bitmap arrow = green ? mBitmapArrowGreenUp : mBitmapArrowRedUp;
- Matrix matrix = new Matrix();
final int cellWidth = mBitmapCircleDefault.getWidth();
final int cellHeight = mBitmapCircleDefault.getHeight();
@@ -933,10 +933,10 @@
final float angle = (float) Math.toDegrees(theta) + 90.0f;
// compose matrix
- matrix.setTranslate(leftX + offsetX, topY + offsetY); // transform to cell position
- matrix.preRotate(angle, cellWidth / 2.0f, cellHeight / 2.0f); // rotate about cell center
- matrix.preTranslate((cellWidth - arrow.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
- canvas.drawBitmap(arrow, matrix, mPaint);
+ mArrowMatrix.setTranslate(leftX + offsetX, topY + offsetY); // transform to cell position
+ mArrowMatrix.preRotate(angle, cellWidth / 2.0f, cellHeight / 2.0f); // rotate about cell center
+ mArrowMatrix.preTranslate((cellWidth - arrow.getWidth()) / 2.0f, 0.0f); // translate to 12:00 pos
+ canvas.drawBitmap(arrow, mArrowMatrix, mPaint);
}
/**
diff --git a/core/res/res/layout/text_edit_no_paste_window.xml b/core/res/res/layout/text_edit_no_paste_window.xml
index 84b6103..d409d97 100644
--- a/core/res/res/layout/text_edit_no_paste_window.xml
+++ b/core/res/res/layout/text_edit_no_paste_window.xml
@@ -40,6 +40,7 @@
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@android:string/pasteDisabled"
+ android:textColor="@android:color/dim_foreground_dark_inverse_disabled"
android:layout_toRightOf="@id/paste_icon"
/>
diff --git a/core/res/res/layout/text_edit_paste_window.xml b/core/res/res/layout/text_edit_paste_window.xml
index 369f4a5..d153365 100644
--- a/core/res/res/layout/text_edit_paste_window.xml
+++ b/core/res/res/layout/text_edit_paste_window.xml
@@ -40,6 +40,7 @@
android:layout_centerVertical="true"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
android:text="@android:string/paste"
+ android:textColor="@android:color/black"
android:layout_toRightOf="@id/paste_icon"
/>
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
index 6adfc74..3a78f26 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerUnitTestRunner.java
@@ -20,6 +20,7 @@
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import android.util.Log;
+import com.android.connectivitymanagertest.unit.WifiClientTest;
import com.android.connectivitymanagertest.unit.WifiSoftAPTest;
import junit.framework.TestSuite;
@@ -35,6 +36,7 @@
@Override
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(WifiClientTest.class);
suite.addTestSuite(WifiSoftAPTest.class);
return suite;
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
new file mode 100644
index 0000000..6717bda
--- /dev/null
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/unit/WifiClientTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.connectivitymanagertest.unit;
+
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.Context;
+import android.app.Instrumentation;
+import android.os.Handler;
+import android.os.Message;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
+import android.net.wifi.WifiConfiguration.Status;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import android.util.Log;
+
+/**
+ * Test wifi client
+ */
+public class WifiClientTest extends AndroidTestCase {
+
+ private WifiManager mWifiManager;
+ private final String TAG = "WifiClientTest";
+
+ //10s delay for turning on wifi
+ private static final int DELAY = 10000;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+ mWifiManager.setWifiEnabled(true);
+ assertNotNull(mWifiManager);
+ }
+
+ private void sleepAfterWifiEnable() {
+ try {
+ Thread.sleep(DELAY);
+ } catch (Exception e) {
+ fail("Sleep timeout " + e);
+ }
+ }
+
+ // Test case 1: add/remove a open network
+ @LargeTest
+ public void testAddRemoveNetwork() {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "\"TestSSID1\"";
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+
+ //add
+ int netId = mWifiManager.addNetwork(config);
+ assertTrue(netId != -1);
+
+ //check config list
+ List<WifiConfiguration> configList = mWifiManager.getConfiguredNetworks();
+ boolean found = false;
+ for (WifiConfiguration c : configList) {
+ if (c.networkId == netId) {
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ //remove
+ boolean ret = mWifiManager.removeNetwork(netId);
+ assertTrue(ret);
+
+ //check config list
+ configList = mWifiManager.getConfiguredNetworks();
+ found = false;
+ for (WifiConfiguration c : configList) {
+ if (c.networkId == netId) {
+ found = true;
+ }
+ }
+
+ assertFalse(found);
+ }
+
+ // Test case 2: enable/disable a open network
+ @LargeTest
+ public void testEnableDisableNetwork() {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "\"TestSSID2\"";
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+
+ //add
+ int netId = mWifiManager.addNetwork(config);
+ assertTrue(netId != -1);
+
+ //enable network and disable others
+ boolean ret = mWifiManager.enableNetwork(netId, true);
+ assertTrue(ret);
+
+ //check config list
+ List<WifiConfiguration> configList = mWifiManager.getConfiguredNetworks();
+ for (WifiConfiguration c : configList) {
+ if (c.networkId == netId) {
+ assertTrue(c.status == Status.ENABLED);
+ } else {
+ assertFalse(c.status == Status.ENABLED);
+ }
+ }
+
+ //disable network
+ ret = mWifiManager.disableNetwork(netId);
+ assertTrue(ret);
+
+ //check config list
+ configList = mWifiManager.getConfiguredNetworks();
+ for (WifiConfiguration c : configList) {
+ if (c.networkId == netId) {
+ assertTrue(c.status == Status.DISABLED);
+ }
+ }
+ }
+
+ // Test case 3: ping supplicant
+ @LargeTest
+ public void testPingSupplicant() {
+ assertTrue(mWifiManager.pingSupplicant());
+ mWifiManager.setWifiEnabled(false);
+ sleepAfterWifiEnable();
+
+ assertFalse(mWifiManager.pingSupplicant());
+ mWifiManager.setWifiEnabled(true);
+ sleepAfterWifiEnable();
+ }
+
+ // Test case 4: save config
+ @LargeTest
+ public void testSaveConfig() {
+ WifiConfiguration config = new WifiConfiguration();
+ config.SSID = "\"TestSSID3\"";
+ config.allowedKeyManagement.set(KeyMgmt.NONE);
+
+ //add
+ int netId = mWifiManager.addNetwork(config);
+ assertTrue(netId != -1);
+
+ mWifiManager.saveConfiguration();
+
+ //restart wifi
+ mWifiManager.setWifiEnabled(false);
+ mWifiManager.setWifiEnabled(true);
+
+ sleepAfterWifiEnable();
+
+ //check config list
+ List<WifiConfiguration> configList = mWifiManager.getConfiguredNetworks();
+ boolean found = false;
+ for (WifiConfiguration c : configList) {
+ if (c.SSID.equals("TestSSID3")) {
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ //restore config
+ boolean ret = mWifiManager.removeNetwork(netId);
+ assertTrue(ret);
+ mWifiManager.saveConfiguration();
+ }
+}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index d661f7b..29158e5 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -38,7 +38,7 @@
LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
- LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia
+ LOCAL_SHARED_LIBRARIES := libcutils libutils libGLESv2 libskia libui
LOCAL_MODULE := libhwui
LOCAL_MODULE_TAGS := optional
LOCAL_PRELINK_MODULE := false
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 0994d82..93c5b34 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -46,18 +46,21 @@
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
mCurrentBuffer = meshBuffer;
+ mRegionMesh = NULL;
}
-/**
- * Binds the VBO used to render simple textured quads.
- */
+Caches::~Caches() {
+ delete[] mRegionMesh;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// VBO
+///////////////////////////////////////////////////////////////////////////////
+
void Caches::bindMeshBuffer() {
bindMeshBuffer(meshBuffer);
}
-/**
- * Binds the specified VBO.
- */
void Caches::bindMeshBuffer(const GLuint buffer) {
if (mCurrentBuffer != buffer) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
@@ -65,9 +68,6 @@
}
}
-/**
- * Unbinds the VBO used to render simple textured quads.
- */
void Caches::unbindMeshBuffer() {
if (mCurrentBuffer) {
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -75,5 +75,35 @@
}
}
+TextureVertex* Caches::getRegionMesh() {
+ // Create the mesh, 2 triangles and 4 vertices per rectangle in the region
+ if (!mRegionMesh) {
+ mRegionMesh = new TextureVertex[REGION_MESH_QUAD_COUNT * 4];
+
+ uint16_t* regionIndices = new uint16_t[REGION_MESH_QUAD_COUNT * 6];
+ for (int i = 0; i < REGION_MESH_QUAD_COUNT; i++) {
+ uint16_t quad = i * 4;
+ int index = i * 6;
+ regionIndices[index ] = quad; // top-left
+ regionIndices[index + 1] = quad + 1; // top-right
+ regionIndices[index + 2] = quad + 2; // bottom-left
+ regionIndices[index + 3] = quad + 2; // bottom-left
+ regionIndices[index + 4] = quad + 1; // top-right
+ regionIndices[index + 5] = quad + 3; // bottom-right
+ }
+
+ glGenBuffers(1, &mRegionMeshIndices);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, REGION_MESH_QUAD_COUNT * 6 * sizeof(uint16_t),
+ regionIndices, GL_STATIC_DRAW);
+
+ delete[] regionIndices;
+ } else {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mRegionMeshIndices);
+ }
+
+ return mRegionMesh;
+}
+
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index ca22867..c019fd1 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_CACHES_H
-#define ANDROID_UI_CACHES_H
+#ifndef ANDROID_HWUI_CACHES_H
+#define ANDROID_HWUI_CACHES_H
#ifndef LOG_TAG
#define LOG_TAG "OpenGLRenderer"
@@ -46,6 +46,8 @@
#define REQUIRED_TEXTURE_UNITS_COUNT 3
+#define REGION_MESH_QUAD_COUNT 512
+
// Generates simple and textured vertices
#define FV(x, y, u, v) { { x, y }, { u, v } }
@@ -77,6 +79,7 @@
class Caches: public Singleton<Caches> {
Caches();
+ ~Caches();
friend class Singleton<Caches>;
@@ -84,11 +87,33 @@
GLuint mCurrentBuffer;
+ // Used to render layers
+ TextureVertex* mRegionMesh;
+ GLuint mRegionMeshIndices;
+
public:
+ /**
+ * Binds the VBO used to render simple textured quads.
+ */
void bindMeshBuffer();
+
+ /**
+ * Binds the specified VBO if needed.
+ */
void bindMeshBuffer(const GLuint buffer);
+
+ /**
+ * Unbinds the VBO used to render simple textured quads.
+ */
void unbindMeshBuffer();
+ /**
+ * Returns the mesh used to draw regions. Calling this method will
+ * bind a VBO of type GL_ELEMENT_ARRAY_BUFFER that contains the
+ * indices for the region mesh.
+ */
+ TextureVertex* getRegionMesh();
+
bool blend;
GLenum lastSrcMode;
GLenum lastDstMode;
@@ -118,7 +143,6 @@
}; // class Caches
}; // namespace uirenderer
-
}; // namespace android
-#endif // ANDROID_UI_CACHES_H
+#endif // ANDROID_HWUI_CACHES_H
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 0dd9c5a..23ccef6 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -169,7 +169,8 @@
int saveCount = renderer.getSaveCount() - 1;
while (!mReader.eof()) {
- switch (mReader.readInt()) {
+ int op = mReader.readInt();
+ switch (op) {
case AcquireContext: {
renderer.acquireContext();
}
@@ -195,6 +196,11 @@
getPaint(), getInt());
}
break;
+ case SaveLayerAlpha: {
+ renderer.saveLayerAlpha(getFloat(), getFloat(), getFloat(), getFloat(),
+ getInt(), getInt());
+ }
+ break;
case Translate: {
renderer.translate(getFloat(), getFloat());
}
@@ -400,6 +406,15 @@
return OpenGLRenderer::save(flags);
}
+int DisplayListRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
+ int alpha, int flags) {
+ addOp(DisplayList::SaveLayerAlpha);
+ addBounds(left, top, right, bottom);
+ addInt(alpha);
+ addInt(flags);
+ return OpenGLRenderer::save(flags);
+}
+
void DisplayListRenderer::translate(float dx, float dy) {
addOp(DisplayList::Translate);
addPoint(dx, dy);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 6636de6..fd69fab 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_DISPLAY_LIST_RENDERER_H
-#define ANDROID_UI_DISPLAY_LIST_RENDERER_H
+#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
+#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
#include <SkChunkAlloc.h>
#include <SkFlattenable.h>
@@ -85,6 +85,7 @@
Restore,
RestoreToCount,
SaveLayer,
+ SaveLayerAlpha,
Translate,
Rotate,
Scale,
@@ -222,6 +223,8 @@
int saveLayer(float left, float top, float right, float bottom,
SkPaint* p, int flags);
+ int saveLayerAlpha(float left, float top, float right, float bottom,
+ int alpha, int flags);
void translate(float dx, float dy);
void rotate(float degrees);
@@ -411,4 +414,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_DISPLAY_LIST_RENDERER_H
+#endif // ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
diff --git a/libs/hwui/Extensions.h b/libs/hwui/Extensions.h
index d50d36e..eceb5c1c 100644
--- a/libs/hwui/Extensions.h
+++ b/libs/hwui/Extensions.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_EXTENSIONS_H
-#define ANDROID_UI_EXTENSIONS_H
+#ifndef ANDROID_HWUI_EXTENSIONS_H
+#define ANDROID_HWUI_EXTENSIONS_H
#include <utils/SortedVector.h>
#include <utils/String8.h>
@@ -93,4 +93,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_EXTENSIONS_H
+#endif // ANDROID_HWUI_EXTENSIONS_H
diff --git a/libs/hwui/FboCache.h b/libs/hwui/FboCache.h
index ec4afe9..ad6cc3e 100644
--- a/libs/hwui/FboCache.h
+++ b/libs/hwui/FboCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_FBO_CACHE_H
-#define ANDROID_UI_FBO_CACHE_H
+#ifndef ANDROID_HWUI_FBO_CACHE_H
+#define ANDROID_HWUI_FBO_CACHE_H
#include <GLES2/gl2.h>
@@ -76,4 +76,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_FBO_CACHE_H
+#endif // ANDROID_HWUI_FBO_CACHE_H
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index e1a236c..5224689 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -556,6 +556,8 @@
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBufferID);
glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);
+
+ mDrawn = true;
}
void FontRenderer::appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2,
@@ -595,6 +597,13 @@
mCurrentQuadIndex++;
+ if (mBounds) {
+ mBounds->left = fmin(mBounds->left, x1);
+ mBounds->top = fmin(mBounds->top, y3);
+ mBounds->right = fmax(mBounds->right, x3);
+ mBounds->bottom = fmax(mBounds->bottom, y1);
+ }
+
if (mCurrentQuadIndex == mMaxNumberOfQuads) {
issueDrawCommand();
mCurrentQuadIndex = 0;
@@ -674,22 +683,27 @@
return image;
}
-void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
- uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y) {
+bool FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
+ uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, Rect* bounds) {
checkInit();
if (!mCurrentFont) {
LOGE("No font set");
- return;
+ return false;
}
+ mDrawn = false;
+ mBounds = bounds;
mClip = clip;
mCurrentFont->renderUTF(paint, text, startIndex, len, numGlyphs, x, y);
+ mBounds = NULL;
if (mCurrentQuadIndex != 0) {
issueDrawCommand();
mCurrentQuadIndex = 0;
}
+
+ return mDrawn;
}
void FontRenderer::computeGaussianWeights(float* weights, int32_t radius) {
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index f10efad..a76cb86 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_FONT_RENDERER_H
-#define ANDROID_UI_FONT_RENDERER_H
+#ifndef ANDROID_HWUI_FONT_RENDERER_H
+#define ANDROID_HWUI_FONT_RENDERER_H
#include <utils/String8.h>
#include <utils/String16.h>
@@ -132,8 +132,8 @@
}
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
- void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
- uint32_t len, int numGlyphs, int x, int y);
+ bool renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
+ uint32_t len, int numGlyphs, int x, int y, Rect* bounds);
struct DropShadow {
DropShadow() { };
@@ -257,6 +257,8 @@
uint32_t mIndexBufferID;
const Rect* mClip;
+ Rect* mBounds;
+ bool mDrawn;
bool mInitialized;
@@ -273,4 +275,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_FONT_RENDERER_H
+#endif // ANDROID_HWUI_FONT_RENDERER_H
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
index 5fa45cf..b59ae81 100644
--- a/libs/hwui/GammaFontRenderer.h
+++ b/libs/hwui/GammaFontRenderer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_GAMMA_FONT_RENDERER_H
-#define ANDROID_UI_GAMMA_FONT_RENDERER_H
+#ifndef ANDROID_HWUI_GAMMA_FONT_RENDERER_H
+#define ANDROID_HWUI_GAMMA_FONT_RENDERER_H
#include <SkPaint.h>
@@ -45,4 +45,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_GAMMA_FONT_RENDERER_H
+#endif // ANDROID_HWUI_GAMMA_FONT_RENDERER_H
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 48877f6d3..c9553f4 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_GRADIENT_CACHE_H
-#define ANDROID_UI_GRADIENT_CACHE_H
+#ifndef ANDROID_HWUI_GRADIENT_CACHE_H
+#define ANDROID_HWUI_GRADIENT_CACHE_H
#include <SkShader.h>
@@ -93,4 +93,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_GRADIENT_CACHE_H
+#endif // ANDROID_HWUI_GRADIENT_CACHE_H
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index 2afe2fa..a780183 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_LAYER_H
-#define ANDROID_UI_LAYER_H
+#ifndef ANDROID_HWUI_LAYER_H
+#define ANDROID_HWUI_LAYER_H
#include <sys/types.h>
#include <GLES2/gl2.h>
+#include <ui/Region.h>
+
#include <SkXfermode.h>
#include "Rect.h"
@@ -85,9 +87,15 @@
* Height of the layer texture.
*/
uint32_t height;
+
+ /**
+ * Dirty region indicating what parts of the layer
+ * have been drawn.
+ */
+ Region region;
}; // struct Layer
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_LAYER_H
+#endif // ANDROID_HWUI_LAYER_H
diff --git a/libs/hwui/LayerCache.h b/libs/hwui/LayerCache.h
index ae792ab..4df8ab3 100644
--- a/libs/hwui/LayerCache.h
+++ b/libs/hwui/LayerCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_LAYER_CACHE_H
-#define ANDROID_UI_LAYER_CACHE_H
+#ifndef ANDROID_HWUI_LAYER_CACHE_H
+#define ANDROID_HWUI_LAYER_CACHE_H
#include "Layer.h"
#include "utils/SortedList.h"
@@ -138,4 +138,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_LAYER_CACHE_H
+#endif // ANDROID_HWUI_LAYER_CACHE_H
diff --git a/libs/hwui/Line.h b/libs/hwui/Line.h
index c529354..5c6f3d8 100644
--- a/libs/hwui/Line.h
+++ b/libs/hwui/Line.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_LINE_H
-#define ANDROID_UI_LINE_H
+#ifndef ANDROID_HWUI_LINE_H
+#define ANDROID_HWUI_LINE_H
#include <GLES2/gl2.h>
@@ -123,4 +123,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_LINE_H
+#endif // ANDROID_HWUI_LINE_H
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 83ea615..7462d5b 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -271,6 +271,19 @@
MUL_ADD_STORE(r.right, data[kScaleX], data[kTranslateX]);
MUL_ADD_STORE(r.top, data[kScaleY], data[kTranslateY]);
MUL_ADD_STORE(r.bottom, data[kScaleY], data[kTranslateY]);
+
+ if (r.left > r.right) {
+ float x = r.left;
+ r.left = r.right;
+ r.right = x;
+ }
+
+ if (r.top > r.bottom) {
+ float y = r.top;
+ r.top = r.bottom;
+ r.bottom = y;
+ }
+
return;
}
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index fe81159..d678bd0 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_MATRIX_H
-#define ANDROID_UI_MATRIX_H
+#ifndef ANDROID_HWUI_MATRIX_H
+#define ANDROID_HWUI_MATRIX_H
#include <SkMatrix.h>
@@ -137,4 +137,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_MATRIX_H
+#endif // ANDROID_HWUI_MATRIX_H
diff --git a/libs/hwui/OpenGLDebugRenderer.h b/libs/hwui/OpenGLDebugRenderer.h
index ce6a4aa..7787ff1 100644
--- a/libs/hwui/OpenGLDebugRenderer.h
+++ b/libs/hwui/OpenGLDebugRenderer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_OPENGL_DEBUG_RENDERER_H
-#define ANDROID_UI_OPENGL_DEBUG_RENDERER_H
+#ifndef ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
+#define ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
#include "OpenGLRenderer.h"
@@ -66,4 +66,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_OPENGL_DEBUG_RENDERER_H
+#endif // ANDROID_HWUI_OPENGL_DEBUG_RENDERER_H
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index b167131..0f0316f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -26,6 +26,8 @@
#include <utils/Log.h>
#include <utils/StopWatch.h>
+#include <ui/Rect.h>
+
#include "OpenGLRenderer.h"
namespace android {
@@ -285,7 +287,7 @@
int OpenGLRenderer::saveLayerAlpha(float left, float top, float right, float bottom,
int alpha, int flags) {
- if (alpha == 0xff) {
+ if (alpha >= 255 - ALPHA_THRESHOLD) {
return saveLayer(left, top, right, bottom, NULL, flags);
} else {
SkPaint paint;
@@ -377,7 +379,6 @@
bounds.getHeight() > mCaches.maxTextureSize) {
snapshot->invisible = true;
} else {
- // TODO: Should take the mode into account
snapshot->invisible = snapshot->previous->invisible ||
(alpha <= ALPHA_THRESHOLD && fboLayer);
}
@@ -387,8 +388,7 @@
return false;
}
- glActiveTexture(GL_TEXTURE0);
-
+ glActiveTexture(gTextureUnits[0]);
Layer* layer = mCaches.layerCache.get(bounds.getWidth(), bounds.getHeight());
if (!layer) {
return false;
@@ -405,56 +405,7 @@
snapshot->layer = layer;
if (fboLayer) {
- layer->fbo = mCaches.fboCache.get();
-
- snapshot->flags |= Snapshot::kFlagIsFboLayer;
- snapshot->fbo = layer->fbo;
- snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
- snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
- snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
- snapshot->height = bounds.getHeight();
- snapshot->flags |= Snapshot::kFlagDirtyOrtho;
- snapshot->orthoMatrix.load(mOrthoMatrix);
-
- // Bind texture to FBO
- glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
- glBindTexture(GL_TEXTURE_2D, layer->texture);
-
- // Initialize the texture if needed
- if (layer->empty) {
- layer->empty = false;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->width, layer->height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- layer->texture, 0);
-
-#if DEBUG_LAYERS
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- LOGE("Framebuffer incomplete (GL error code 0x%x)", status);
-
- glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
- glDeleteTextures(1, &layer->texture);
- mCaches.fboCache.put(layer->fbo);
-
- delete layer;
-
- return false;
- }
-#endif
-
- // Clear the FBO
- glScissor(0.0f, 0.0f, bounds.getWidth() + 1.0f, bounds.getHeight() + 1.0f);
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
-
- dirtyClip();
-
- // Change the ortho projection
- glViewport(0, 0, bounds.getWidth(), bounds.getHeight());
- mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
+ return createFboLayer(layer, bounds, snapshot, previousFbo);
} else {
// Copy the framebuffer into the layer
glBindTexture(GL_TEXTURE_2D, layer->texture);
@@ -475,6 +426,82 @@
return true;
}
+bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> snapshot,
+ GLuint previousFbo) {
+ layer->fbo = mCaches.fboCache.get();
+
+#if RENDER_LAYERS_AS_REGIONS
+ snapshot->region = &snapshot->layer->region;
+ snapshot->flags |= Snapshot::kFlagFboTarget;
+#endif
+
+ Rect clip(bounds);
+ snapshot->transform->mapRect(clip);
+ clip.intersect(*snapshot->clipRect);
+ clip.snapToPixelBoundaries();
+ clip.intersect(snapshot->previous->viewport);
+
+ mat4 inverse;
+ inverse.loadInverse(*mSnapshot->transform);
+
+ inverse.mapRect(clip);
+ clip.snapToPixelBoundaries();
+ clip.intersect(bounds);
+
+ snapshot->flags |= Snapshot::kFlagIsFboLayer;
+ snapshot->fbo = layer->fbo;
+ snapshot->resetTransform(-bounds.left, -bounds.top, 0.0f);
+ //snapshot->resetClip(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
+ snapshot->resetClip(clip.left, clip.top, clip.right, clip.bottom);
+ snapshot->viewport.set(0.0f, 0.0f, bounds.getWidth(), bounds.getHeight());
+ snapshot->height = bounds.getHeight();
+ snapshot->flags |= Snapshot::kFlagDirtyOrtho;
+ snapshot->orthoMatrix.load(mOrthoMatrix);
+
+ // Bind texture to FBO
+ glBindFramebuffer(GL_FRAMEBUFFER, layer->fbo);
+ glBindTexture(GL_TEXTURE_2D, layer->texture);
+
+ // Initialize the texture if needed
+ if (layer->empty) {
+ layer->empty = false;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layer->width, layer->height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ layer->texture, 0);
+
+#if DEBUG_LAYERS_AS_REGIONS
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ LOGE("Framebuffer incomplete (GL error code 0x%x)", status);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, previousFbo);
+ glDeleteTextures(1, &layer->texture);
+ mCaches.fboCache.put(layer->fbo);
+
+ delete layer;
+
+ return false;
+ }
+#endif
+
+ // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering
+ glScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f,
+ clip.getWidth() + 2.0f, clip.getHeight() + 2.0f);
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ dirtyClip();
+
+ // Change the ortho projection
+ glViewport(0, 0, bounds.getWidth(), bounds.getHeight());
+ mOrthoMatrix.loadOrtho(0.0f, bounds.getWidth(), bounds.getHeight(), 0.0f, -1.0f, 1.0f);
+
+ return true;
+}
+
/**
* Read the documentation of createLayer() before doing anything in this method.
*/
@@ -484,42 +511,36 @@
return;
}
- const bool fboLayer = current->flags & SkCanvas::kClipToLayer_SaveFlag;
+ const bool fboLayer = current->flags & Snapshot::kFlagIsFboLayer;
if (fboLayer) {
// Unbind current FBO and restore previous one
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
}
- // Restore the clip from the previous snapshot
- Rect& clip(*previous->clipRect);
- clip.snapToPixelBoundaries();
- glScissor(clip.left, previous->height - clip.bottom, clip.getWidth(), clip.getHeight());
-
Layer* layer = current->layer;
const Rect& rect = layer->layer;
if (!fboLayer && layer->alpha < 255) {
drawColorRect(rect.left, rect.top, rect.right, rect.bottom,
layer->alpha << 24, SkXfermode::kDstIn_Mode, true);
+ // Required below, composeLayerRect() will divide by 255
+ layer->alpha = 255;
}
- const Rect& texCoords = layer->texCoords;
mCaches.unbindMeshBuffer();
- resetDrawTextureTexCoords(texCoords.left, texCoords.top, texCoords.right, texCoords.bottom);
glActiveTexture(gTextureUnits[0]);
- if (fboLayer) {
- drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
- layer->alpha / 255.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
- &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount);
- } else {
- drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
- 1.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
- &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount, true, true);
- }
- resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
+ // When the layer is stored in an FBO, we can save a bit of fillrate by
+ // drawing only the dirty region
+ if (fboLayer) {
+ dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *previous->transform);
+ composeLayerRegion(layer, rect);
+ } else {
+ dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+ composeLayerRect(layer, rect, true);
+ }
if (fboLayer) {
// Detach the texture from the FBO
@@ -541,6 +562,159 @@
}
}
+void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap) {
+ const Rect& texCoords = layer->texCoords;
+ resetDrawTextureTexCoords(texCoords.left, texCoords.top, texCoords.right, texCoords.bottom);
+
+ drawTextureMesh(rect.left, rect.top, rect.right, rect.bottom, layer->texture,
+ layer->alpha / 255.0f, layer->mode, layer->blend, &mMeshVertices[0].position[0],
+ &mMeshVertices[0].texture[0], GL_TRIANGLE_STRIP, gMeshCount, swap, swap);
+
+ resetDrawTextureTexCoords(0.0f, 0.0f, 1.0f, 1.0f);
+}
+
+void OpenGLRenderer::composeLayerRegion(Layer* layer, const Rect& rect) {
+#if RENDER_LAYERS_AS_REGIONS
+ if (layer->region.isRect()) {
+ composeLayerRect(layer, rect);
+ layer->region.clear();
+ return;
+ }
+
+ if (!layer->region.isEmpty()) {
+ size_t count;
+ const android::Rect* rects = layer->region.getArray(&count);
+
+ setupDraw();
+
+ ProgramDescription description;
+ description.hasTexture = true;
+
+ const float alpha = layer->alpha / 255.0f;
+ const bool setColor = description.setColor(alpha, alpha, alpha, alpha);
+ chooseBlending(layer->blend || layer->alpha < 255, layer->mode, description, false);
+
+ useProgram(mCaches.programCache.get(description));
+
+ // Texture
+ bindTexture(layer->texture);
+ glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0);
+
+ // Always premultiplied
+ if (setColor) {
+ mCaches.currentProgram->setColor(alpha, alpha, alpha, alpha);
+ }
+
+ // Mesh
+ int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords");
+ glEnableVertexAttribArray(texCoordsSlot);
+
+ mModelView.loadIdentity();
+ mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+
+ const float texX = 1.0f / float(layer->width);
+ const float texY = 1.0f / float(layer->height);
+
+ TextureVertex* mesh = mCaches.getRegionMesh();
+ GLsizei numQuads = 0;
+
+ glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mesh[0].position[0]);
+ glVertexAttribPointer(texCoordsSlot, 2, GL_FLOAT, GL_FALSE,
+ gMeshStride, &mesh[0].texture[0]);
+
+ for (size_t i = 0; i < count; i++) {
+ const android::Rect* r = &rects[i];
+
+ const float u1 = r->left * texX;
+ const float v1 = (rect.getHeight() - r->top) * texY;
+ const float u2 = r->right * texX;
+ const float v2 = (rect.getHeight() - r->bottom) * texY;
+
+ // TODO: Reject quads outside of the clip
+ TextureVertex::set(mesh++, r->left, r->top, u1, v1);
+ TextureVertex::set(mesh++, r->right, r->top, u2, v1);
+ TextureVertex::set(mesh++, r->left, r->bottom, u1, v2);
+ TextureVertex::set(mesh++, r->right, r->bottom, u2, v2);
+
+ numQuads++;
+
+ if (numQuads >= REGION_MESH_QUAD_COUNT) {
+ glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, NULL);
+ numQuads = 0;
+ mesh = mCaches.getRegionMesh();
+ }
+ }
+
+ if (numQuads > 0) {
+ glDrawElements(GL_TRIANGLES, numQuads * 6, GL_UNSIGNED_SHORT, NULL);
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glDisableVertexAttribArray(texCoordsSlot);
+
+#if DEBUG_LAYERS_AS_REGIONS
+ uint32_t colors[] = {
+ 0x7fff0000, 0x7f00ff00,
+ 0x7f0000ff, 0x7fff00ff,
+ };
+
+ int offset = 0;
+ int32_t top = rects[0].top;
+ int i = 0;
+
+ for (size_t i = 0; i < count; i++) {
+ if (top != rects[i].top) {
+ offset ^= 0x2;
+ top = rects[i].top;
+ }
+
+ Rect r(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
+ drawColorRect(r.left, r.top, r.right, r.bottom, colors[offset + (i & 0x1)],
+ SkXfermode::kSrcOver_Mode);
+ }
+#endif
+
+ layer->region.clear();
+ }
+#else
+ composeLayerRect(layer, rect);
+#endif
+}
+
+void OpenGLRenderer::dirtyLayer(const float left, const float top,
+ const float right, const float bottom, const mat4 transform) {
+#if RENDER_LAYERS_AS_REGIONS
+ if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ Rect bounds(left, top, right, bottom);
+ transform.mapRect(bounds);
+ bounds.intersect(*mSnapshot->clipRect);
+ bounds.snapToPixelBoundaries();
+
+ android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ if (!dirty.isEmpty()) {
+ mSnapshot->region->orSelf(dirty);
+ }
+ }
+#endif
+}
+
+void OpenGLRenderer::dirtyLayer(const float left, const float top,
+ const float right, const float bottom) {
+#if RENDER_LAYERS_AS_REGIONS
+ if ((mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region) {
+ Rect bounds(left, top, right, bottom);
+ bounds.intersect(*mSnapshot->clipRect);
+ bounds.snapToPixelBoundaries();
+
+ android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ if (!dirty.isEmpty()) {
+ mSnapshot->region->orSelf(dirty);
+ }
+ }
+#endif
+}
+
void OpenGLRenderer::setupDraw() {
clearLayerRegions();
if (mDirtyClip) {
@@ -551,21 +725,26 @@
void OpenGLRenderer::clearLayerRegions() {
if (mLayers.size() == 0 || mSnapshot->invisible) return;
+ Rect clipRect(*mSnapshot->clipRect);
+ clipRect.snapToPixelBoundaries();
+
for (uint32_t i = 0; i < mLayers.size(); i++) {
Rect* bounds = mLayers.itemAt(i);
+ if (clipRect.intersects(*bounds)) {
+ // Clear the framebuffer where the layer will draw
+ glScissor(bounds->left, mSnapshot->height - bounds->bottom,
+ bounds->getWidth(), bounds->getHeight());
+ glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
- // Clear the framebuffer where the layer will draw
- glScissor(bounds->left, mSnapshot->height - bounds->bottom,
- bounds->getWidth(), bounds->getHeight());
- glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+ // Restore the clip
+ dirtyClip();
+ }
delete bounds;
}
- mLayers.clear();
- // Restore the clip
- dirtyClip();
+ mLayers.clear();
}
///////////////////////////////////////////////////////////////////////////////
@@ -678,7 +857,12 @@
if (!texture) return;
const AutoTexture autoCleanup(texture);
- drawTextureRect(r.left, r.top, r.right, r.bottom, texture, paint);
+ // This could be done in a cheaper way, all we need is pass the matrix
+ // to the vertex shader. The save/restore is a bit overkill.
+ save(SkCanvas::kMatrix_SaveFlag);
+ concatMatrix(matrix);
+ drawTextureRect(0.0f, 0.0f, bitmap->width(), bitmap->height(), texture, paint);
+ restore();
}
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
@@ -738,11 +922,21 @@
right - left, bottom - top, xDivs, yDivs, colors, width, height, numColors);
if (mesh) {
- // Specify right and bottom as +1.0f from left/top to prevent scaling since the
- // patch mesh already defines the final size
- drawTextureMesh(left, top, left + 1.0f, top + 1.0f, texture->id, alpha / 255.0f,
+ // Mark the current layer dirty where we are going to draw the patch
+ if ((mSnapshot->flags & Snapshot::kFlagFboTarget) &&
+ mSnapshot->region && mesh->hasEmptyQuads) {
+ const size_t count = mesh->quads.size();
+ for (size_t i = 0; i < count; i++) {
+ Rect bounds = mesh->quads.itemAt(i);
+ dirtyLayer(bounds.left, bounds.top, bounds.right, bounds.bottom,
+ *mSnapshot->transform);
+ }
+ }
+
+ drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f,
mode, texture->blend, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
- GL_TRIANGLES, mesh->verticesCount, false, false, mesh->meshBuffer);
+ GL_TRIANGLES, mesh->verticesCount, false, false, mesh->meshBuffer,
+ true, !mesh->hasEmptyQuads);
}
}
@@ -801,6 +995,7 @@
mModelView.scale(length, strokeWidth, 1.0f);
}
mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+ // TODO: Add bounds to the layer's region
if (mShader) {
mShader->updateTransforms(mCaches.currentProgram, mModelView, *mSnapshot);
@@ -904,13 +1099,34 @@
// Assume that the modelView matrix does not force scales, rotates, etc.
const bool linearFilter = mSnapshot->transform->changesBounds();
+
+ // Dimensions are set to (0,0), the layer (if any) won't be dirtied
setupTextureAlpha8(fontRenderer.getTexture(linearFilter), 0, 0, textureUnit,
x, y, r, g, b, a, mode, false, true, NULL, NULL);
const Rect& clip = mSnapshot->getLocalClip();
+ Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
+
+#if RENDER_LAYERS_AS_REGIONS
+ bool hasLayer = (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
+#else
+ bool hasLayer = false;
+#endif
mCaches.unbindMeshBuffer();
- fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
+ if (fontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y,
+ hasLayer ? &bounds : NULL)) {
+#if RENDER_LAYERS_AS_REGIONS
+ if (hasLayer) {
+ mSnapshot->transform->mapRect(bounds);
+ bounds.intersect(*mSnapshot->clipRect);
+ bounds.snapToPixelBoundaries();
+
+ android::Rect dirty(bounds.left, bounds.top, bounds.right, bounds.bottom);
+ mSnapshot->region->orSelf(dirty);
+ }
+#endif
+ }
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(mCaches.currentProgram->getAttrib("texCoords"));
@@ -1081,7 +1297,12 @@
} else {
mModelView.loadIdentity();
}
+
mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+ if (width > 0 && height > 0) {
+ dirtyLayer(x, y, x + width, y + height, *mSnapshot->transform);
+ }
+
if (setColor) {
mCaches.currentProgram->setColor(r, g, b, a);
}
@@ -1214,9 +1435,11 @@
mModelView.scale(right - left, bottom - top, 1.0f);
if (!ignoreTransform) {
mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+ dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
} else {
mat4 identity;
mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
+ dirtyLayer(left, top, right, bottom);
}
mCaches.currentProgram->setColor(r, g, b, a);
@@ -1251,7 +1474,7 @@
void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float bottom,
GLuint texture, float alpha, SkXfermode::Mode mode, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
- bool swapSrcDst, bool ignoreTransform, GLuint vbo) {
+ bool swapSrcDst, bool ignoreTransform, GLuint vbo, bool ignoreScale, bool dirty) {
setupDraw();
ProgramDescription description;
@@ -1262,16 +1485,20 @@
}
mModelView.loadTranslate(left, top, 0.0f);
- mModelView.scale(right - left, bottom - top, 1.0f);
+ if (!ignoreScale) {
+ mModelView.scale(right - left, bottom - top, 1.0f);
+ }
chooseBlending(blend || alpha < 1.0f, mode, description, swapSrcDst);
useProgram(mCaches.programCache.get(description));
if (!ignoreTransform) {
mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+ if (dirty) dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
} else {
- mat4 m;
- mCaches.currentProgram->set(mOrthoMatrix, mModelView, m);
+ mat4 identity;
+ mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
+ if (dirty) dirtyLayer(left, top, right, bottom);
}
// Texture
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3492d2c..2d612d4 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_OPENGL_RENDERER_H
-#define ANDROID_UI_OPENGL_RENDERER_H
+#ifndef ANDROID_HWUI_OPENGL_RENDERER_H
+#define ANDROID_HWUI_OPENGL_RENDERER_H
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -50,6 +50,10 @@
// Debug
#define DEBUG_OPENGL 1
+// If turned on, layers drawn inside FBOs are optimized with regions
+#define RENDER_LAYERS_AS_REGIONS 0
+#define DEBUG_LAYERS_AS_REGIONS 0
+
///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////
@@ -176,6 +180,34 @@
int alpha, SkXfermode::Mode mode, int flags, GLuint previousFbo);
/**
+ * Creates a new layer stored in the specified snapshot as an FBO.
+ *
+ * @param layer The layer to store as an FBO
+ * @param snapshot The snapshot associated with the new layer
+ * @param bounds The bounds of the layer
+ * @param previousFbo The name of the current framebuffer
+ */
+ bool createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> snapshot,
+ GLuint previousFbo);
+
+ /**
+ * Compose the specified layer as a region.
+ *
+ * @param layer The layer to compose
+ * @param rect The layer's bounds
+ */
+ void composeLayerRegion(Layer* layer, const Rect& rect);
+
+ /**
+ * Compose the specified layer as a simple rectangle.
+ *
+ * @param layer The layer to compose
+ * @param rect The layer's bounds
+ * @param swap If true, the source and destination are swapped
+ */
+ void composeLayerRect(Layer* layer, const Rect& rect, bool swap = false);
+
+ /**
* Clears all the regions corresponding to the current list of layers.
* This method MUST be invoked before any drawing operation.
*/
@@ -192,7 +224,7 @@
* @param color The rectangle's ARGB color, defined as a packed 32 bits word
* @param mode The Skia xfermode to use
* @param ignoreTransform True if the current transform should be ignored
- * @paran ignoreBlending True if the blending is set by the caller
+ * @param ignoreBlending True if the blending is set by the caller
*/
void drawColorRect(float left, float top, float right, float bottom,
int color, SkXfermode::Mode mode, bool ignoreTransform = false);
@@ -252,11 +284,14 @@
* @param swapSrcDst Whether or not the src and dst blending operations should be swapped
* @param ignoreTransform True if the current transform should be ignored
* @param vbo The VBO used to draw the mesh
+ * @param ignoreScale True if the model view matrix should not be scaled
+ * @param dirty True if calling this method should dirty the current layer
*/
void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
float alpha, SkXfermode::Mode mode, bool blend,
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
- bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0);
+ bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
+ bool ignoreScale = false, bool dirty = true);
/**
* Prepares the renderer to draw the specified shadow. The active texture
@@ -411,6 +446,18 @@
mDirtyClip = true;
}
+ /**
+ * Mark the layer as dirty at the specified coordinates. The coordinates
+ * are transformed with the supplied matrix.
+ */
+ void dirtyLayer(const float left, const float top, const float right, const float bottom,
+ const mat4 transform);
+
+ /**
+ * Mark the layer as dirty at the specified coordinates.
+ */
+ void dirtyLayer(const float left, const float top, const float right, const float bottom);
+
// Dimensions of the drawing surface
int mWidth, mHeight;
@@ -462,4 +509,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_OPENGL_RENDERER_H
+#endif // ANDROID_HWUI_OPENGL_RENDERER_H
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 3d21431..9b2d476 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -34,6 +34,7 @@
// 2 triangles per patch, 3 vertices per triangle
verticesCount = ((xCount + 1) * (yCount + 1) - emptyQuads) * 2 * 3;
mVertices = new TextureVertex[verticesCount];
+ hasEmptyQuads = emptyQuads > 0;
glGenBuffers(1, &meshBuffer);
}
@@ -51,6 +52,8 @@
float left, float top, float right, float bottom,
const int32_t* xDivs, const int32_t* yDivs,
const uint32_t width, const uint32_t height, const uint32_t colorKey) {
+ if (hasEmptyQuads) quads.clear();
+
const uint32_t xStretchCount = (width + 1) >> 1;
const uint32_t yStretchCount = (height + 1) >> 1;
@@ -118,7 +121,7 @@
mVertices, GL_STATIC_DRAW);
}
-inline void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
+void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, float v2,
const int32_t xDivs[], uint32_t xCount, float stretchX, float width, float bitmapWidth,
uint32_t& quadCount, const uint32_t colorKey) {
float previousStepX = 0.0f;
@@ -150,12 +153,17 @@
generateQuad(vertex, x1, y1, width, y2, u1, v1, 1.0f, v2, quadCount, colorKey);
}
-inline void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
+void Patch::generateQuad(TextureVertex*& vertex, float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2, uint32_t& quadCount, const uint32_t colorKey) {
if (((colorKey >> quadCount++) & 0x1) == 1) {
return;
}
+ if (hasEmptyQuads) {
+ Rect bounds(x1, y1, x2, y2);
+ quads.add(bounds);
+ }
+
// Left triangle
TextureVertex::set(vertex++, x1, y1, u1, v1);
TextureVertex::set(vertex++, x2, y1, u2, v1);
diff --git a/libs/hwui/Patch.h b/libs/hwui/Patch.h
index ce898937..1e78b2f 100644
--- a/libs/hwui/Patch.h
+++ b/libs/hwui/Patch.h
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PATCH_H
-#define ANDROID_UI_PATCH_H
+#ifndef ANDROID_HWUI_PATCH_H
+#define ANDROID_HWUI_PATCH_H
#include <sys/types.h>
#include <GLES2/gl2.h>
+#include <utils/Vector.h>
+
+#include "Rect.h"
#include "Vertex.h"
#include "utils/Compare.h"
@@ -96,15 +99,17 @@
GLuint meshBuffer;
uint32_t verticesCount;
+ Vector<Rect> quads;
+ bool hasEmptyQuads;
private:
TextureVertex* mVertices;
- static inline void generateRow(TextureVertex*& vertex, float y1, float y2,
+ void generateRow(TextureVertex*& vertex, float y1, float y2,
float v1, float v2, const int32_t xDivs[], uint32_t xCount,
float stretchX, float width, float bitmapWidth,
uint32_t& quadCount, const uint32_t colorKey);
- static inline void generateQuad(TextureVertex*& vertex,
+ void generateQuad(TextureVertex*& vertex,
float x1, float y1, float x2, float y2,
float u1, float v1, float u2, float v2,
uint32_t& quadCount, const uint32_t colorKey);
@@ -113,4 +118,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_PATCH_H
+#endif // ANDROID_HWUI_PATCH_H
diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h
index f4eeb09..deba40d 100644
--- a/libs/hwui/PatchCache.h
+++ b/libs/hwui/PatchCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PATCH_CACHE_H
-#define ANDROID_UI_PATCH_CACHE_H
+#ifndef ANDROID_HWUI_PATCH_CACHE_H
+#define ANDROID_HWUI_PATCH_CACHE_H
#include <utils/KeyedVector.h>
@@ -62,4 +62,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_PATCH_CACHE_H
+#endif // ANDROID_HWUI_PATCH_CACHE_H
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index 9a5fc45..db5ce08 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PATH_CACHE_H
-#define ANDROID_UI_PATH_CACHE_H
+#ifndef ANDROID_HWUI_PATH_CACHE_H
+#define ANDROID_HWUI_PATH_CACHE_H
#include <SkBitmap.h>
#include <SkPaint.h>
@@ -170,4 +170,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_PATH_CACHE_H
+#endif // ANDROID_HWUI_PATH_CACHE_H
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 25674c6..baed5fd7 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -22,12 +22,6 @@
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Shaders
-///////////////////////////////////////////////////////////////////////////////
-
-#define SHADER_SOURCE(name, source) const char* name = #source
-
-///////////////////////////////////////////////////////////////////////////////
// Base program
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h
index 026097c..5981662 100644
--- a/libs/hwui/Program.h
+++ b/libs/hwui/Program.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PROGRAM_H
-#define ANDROID_UI_PROGRAM_H
+#ifndef ANDROID_HWUI_PROGRAM_H
+#define ANDROID_HWUI_PROGRAM_H
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
@@ -131,4 +131,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_PROGRAM_H
+#endif // ANDROID_HWUI_PROGRAM_H
diff --git a/libs/hwui/ProgramCache.h b/libs/hwui/ProgramCache.h
index 9cb13b3..186e869 100644
--- a/libs/hwui/ProgramCache.h
+++ b/libs/hwui/ProgramCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PROGRAM_CACHE_H
-#define ANDROID_UI_PROGRAM_CACHE_H
+#ifndef ANDROID_HWUI_PROGRAM_CACHE_H
+#define ANDROID_HWUI_PROGRAM_CACHE_H
#include <utils/KeyedVector.h>
#include <utils/Log.h>
@@ -258,4 +258,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_PROGRAM_CACHE_H
+#endif // ANDROID_HWUI_PROGRAM_CACHE_H
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index db3cb4d..813392b 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_PROPERTIES_H
-#define ANDROID_UI_PROPERTIES_H
+#ifndef ANDROID_HWUI_PROPERTIES_H
+#define ANDROID_HWUI_PROPERTIES_H
#include <cutils/properties.h>
@@ -45,15 +45,15 @@
#define MB(s) s * 1024 * 1024
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
-#define DEFAULT_LAYER_CACHE_SIZE 6.0f
+#define DEFAULT_LAYER_CACHE_SIZE 8.0f
#define DEFAULT_PATH_CACHE_SIZE 4.0f
#define DEFAULT_PATCH_CACHE_SIZE 512
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
-#define DEFAULT_FBO_CACHE_SIZE 25
+#define DEFAULT_FBO_CACHE_SIZE 12
#define DEFAULT_TEXT_GAMMA 1.4f
#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192
-#endif // ANDROID_UI_PROPERTIES_H
+#endif // ANDROID_HWUI_PROPERTIES_H
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 8f3655c..71951b7 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_RECT_H
-#define ANDROID_UI_RECT_H
+#ifndef ANDROID_HWUI_RECT_H
+#define ANDROID_HWUI_RECT_H
+
+#include <cmath>
#include <utils/Log.h>
@@ -32,25 +34,35 @@
float right;
float bottom;
- Rect():
+ // Used by Region
+ typedef float value_type;
+
+ inline Rect():
left(0),
top(0),
right(0),
bottom(0) {
}
- Rect(float left, float top, float right, float bottom):
+ inline Rect(float left, float top, float right, float bottom):
left(left),
top(top),
right(right),
bottom(bottom) {
}
- Rect(const Rect& r) {
+ inline Rect(float width, float height):
+ left(0.0f),
+ top(0.0f),
+ right(width),
+ bottom(height) {
+ }
+
+ inline Rect(const Rect& r) {
set(r);
}
- Rect(Rect& r) {
+ inline Rect(Rect& r) {
set(r);
}
@@ -72,22 +84,26 @@
return memcmp(&a, &b, sizeof(a));
}
- bool isEmpty() const {
+ inline void clear() {
+ left = top = right = bottom = 0.0f;
+ }
+
+ inline bool isEmpty() const {
return left >= right || top >= bottom;
}
- void setEmpty() {
- memset(this, 0, sizeof(*this));
+ inline void setEmpty() {
+ left = top = right = bottom = 0.0f;
}
- void set(float left, float top, float right, float bottom) {
+ inline void set(float left, float top, float right, float bottom) {
this->left = left;
this->right = right;
this->top = top;
this->bottom = bottom;
}
- void set(const Rect& r) {
+ inline void set(const Rect& r) {
set(r.left, r.top, r.right, r.bottom);
}
@@ -148,6 +164,13 @@
return false;
}
+ void translate(float dx, float dy) {
+ left += dx;
+ right += dx;
+ top += dy;
+ bottom += dy;
+ }
+
void snapToPixelBoundaries() {
left = floorf(left + 0.5f);
top = floorf(top + 0.5f);
@@ -164,4 +187,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_RECT_H
+#endif // ANDROID_HWUI_RECT_H
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
index d9b3718..2256fd1 100644
--- a/libs/hwui/ResourceCache.h
+++ b/libs/hwui/ResourceCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_RESOURCE_CACHE_H
-#define ANDROID_UI_RESOURCE_CACHE_H
+#ifndef ANDROID_HWUI_RESOURCE_CACHE_H
+#define ANDROID_HWUI_RESOURCE_CACHE_H
#include <SkBitmap.h>
#include <SkiaColorFilter.h>
@@ -75,4 +75,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_RESOURCE_CACHE_H
+#endif // ANDROID_HWUI_RESOURCE_CACHE_H
diff --git a/libs/hwui/SkiaColorFilter.h b/libs/hwui/SkiaColorFilter.h
index 17f49f9..bf45e13 100644
--- a/libs/hwui/SkiaColorFilter.h
+++ b/libs/hwui/SkiaColorFilter.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_SKIA_COLOR_FILTER_H
-#define ANDROID_UI_SKIA_COLOR_FILTER_H
+#ifndef ANDROID_HWUI_SKIA_COLOR_FILTER_H
+#define ANDROID_HWUI_SKIA_COLOR_FILTER_H
#include <GLES2/gl2.h>
#include <SkColorFilter.h>
@@ -123,4 +123,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_SKIA_COLOR_FILTER_H
+#endif // ANDROID_HWUI_SKIA_COLOR_FILTER_H
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
index 4cd1b8b..1d884ab 100644
--- a/libs/hwui/SkiaShader.h
+++ b/libs/hwui/SkiaShader.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_SKIA_SHADER_H
-#define ANDROID_UI_SKIA_SHADER_H
+#ifndef ANDROID_HWUI_SKIA_SHADER_H
+#define ANDROID_HWUI_SKIA_SHADER_H
#include <SkShader.h>
#include <SkXfermode.h>
@@ -216,4 +216,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_SKIA_SHADER_H
+#endif // ANDROID_HWUI_SKIA_SHADER_H
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index 2da1950..9f78063 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -14,16 +14,16 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_SNAPSHOT_H
-#define ANDROID_UI_SNAPSHOT_H
+#ifndef ANDROID_HWUI_SNAPSHOT_H
+#define ANDROID_HWUI_SNAPSHOT_H
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <utils/RefBase.h>
+#include <ui/Region.h>
#include <SkCanvas.h>
-#include <SkRegion.h>
#include "Layer.h"
#include "Matrix.h"
@@ -46,6 +46,7 @@
Snapshot(): flags(0), previous(NULL), layer(NULL), fbo(0), invisible(false) {
transform = &mTransformRoot;
clipRect = &mClipRectRoot;
+ region = NULL;
}
/**
@@ -75,6 +76,13 @@
} else {
flags |= Snapshot::kFlagDirtyLocalClip;
}
+
+ if (s->flags & Snapshot::kFlagFboTarget) {
+ flags |= Snapshot::kFlagFboTarget;
+ region = s->region;
+ } else {
+ region = NULL;
+ }
}
/**
@@ -105,6 +113,11 @@
* Indicates that this snapshot has changed the ortho matrix.
*/
kFlagDirtyOrtho = 0x10,
+ /**
+ * Indicates that this snapshot or an ancestor snapshot is
+ * an FBO layer.
+ */
+ kFlagFboTarget = 0x20
};
/**
@@ -243,6 +256,11 @@
*/
Rect* clipRect;
+ /**
+ * The ancestor layer's dirty region..
+ */
+ Region* region;
+
private:
mat4 mTransformRoot;
Rect mClipRectRoot;
@@ -253,4 +271,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_SNAPSHOT_H
+#endif // ANDROID_HWUI_SNAPSHOT_H
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
index 16e2814..adf09e2 100644
--- a/libs/hwui/TextDropShadowCache.h
+++ b/libs/hwui/TextDropShadowCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
-#define ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+#ifndef ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
+#define ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
#include <GLES2/gl2.h>
@@ -148,4 +148,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_TEXT_DROP_SHADOW_CACHE_H
+#endif // ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 755074d..4922bb3 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_TEXTURE_H
-#define ANDROID_UI_TEXTURE_H
+#ifndef ANDROID_HWUI_TEXTURE_H
+#define ANDROID_HWUI_TEXTURE_H
#include <GLES2/gl2.h>
@@ -86,4 +86,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_TEXTURE_H
+#endif // ANDROID_HWUI_TEXTURE_H
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index d860953..0c7948f 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -200,9 +200,13 @@
texture->blend = !bitmap->isOpaque();
break;
case SkBitmap::kIndex8_Config:
- uploadPalettedTexture(resize, bitmap, texture->width, texture->height);
+ uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
texture->blend = false;
break;
+ case SkBitmap::kARGB_4444_Config:
+ uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
+ texture->blend = true;
+ break;
default:
LOGW("Unsupported bitmap config: %d", bitmap->getConfig());
break;
@@ -215,7 +219,7 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
-void TextureCache::uploadPalettedTexture(bool resize, SkBitmap* bitmap,
+void TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
uint32_t width, uint32_t height) {
SkBitmap rgbaBitmap;
rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 6718597..d9d2387 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_TEXTURE_CACHE_H
-#define ANDROID_UI_TEXTURE_CACHE_H
+#ifndef ANDROID_HWUI_TEXTURE_CACHE_H
+#define ANDROID_HWUI_TEXTURE_CACHE_H
#include <SkBitmap.h>
@@ -93,7 +93,7 @@
*/
void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false);
- void uploadPalettedTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
+ void uploadLoFiTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
void uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
GLenum type, const GLvoid * data);
@@ -115,4 +115,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_TEXTURE_CACHE_H
+#endif // ANDROID_HWUI_TEXTURE_CACHE_H
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index 1f54086..bbf4d4a 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_VERTEX_H
-#define ANDROID_UI_VERTEX_H
+#ifndef ANDROID_HWUI_VERTEX_H
+#define ANDROID_HWUI_VERTEX_H
namespace android {
namespace uirenderer {
@@ -43,4 +43,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_VERTEX_H
+#endif // ANDROID_HWUI_VERTEX_H
diff --git a/libs/hwui/utils/Compare.h b/libs/hwui/utils/Compare.h
index 5ea0fc9..6531e78 100644
--- a/libs/hwui/utils/Compare.h
+++ b/libs/hwui/utils/Compare.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_COMPARE_H
-#define ANDROID_UI_COMPARE_H
+#ifndef ANDROID_HWUI_COMPARE_H
+#define ANDROID_HWUI_COMPARE_H
#include <cmath>
@@ -37,4 +37,4 @@
if (a < rhs.a) return true; \
if (a == rhs.a)
-#endif // ANDROID_UI_COMPARE_H
+#endif // ANDROID_HWUI_COMPARE_H
diff --git a/libs/hwui/utils/GenerationCache.h b/libs/hwui/utils/GenerationCache.h
index 5cea30f..2e76236 100644
--- a/libs/hwui/utils/GenerationCache.h
+++ b/libs/hwui/utils/GenerationCache.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_GENERATION_CACHE_H
-#define ANDROID_UI_GENERATION_CACHE_H
+#ifndef ANDROID_HWUI_GENERATION_CACHE_H
+#define ANDROID_HWUI_GENERATION_CACHE_H
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
@@ -242,4 +242,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_GENERATION_CACHE_H
+#endif // ANDROID_HWUI_GENERATION_CACHE_H
diff --git a/libs/hwui/utils/SortedList.h b/libs/hwui/utils/SortedList.h
index 68f5e9d..2fa890a 100644
--- a/libs/hwui/utils/SortedList.h
+++ b/libs/hwui/utils/SortedList.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_SORTED_LIST_H
-#define ANDROID_UI_SORTED_LIST_H
+#ifndef ANDROID_HWUI_SORTED_LIST_H
+#define ANDROID_HWUI_SORTED_LIST_H
#include <stdint.h>
#include <sys/types.h>
@@ -239,4 +239,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_SORTED_LIST_H
+#endif // ANDROID_HWUI_SORTED_LIST_H
diff --git a/libs/hwui/utils/SortedListImpl.h b/libs/hwui/utils/SortedListImpl.h
index 7da09ef..dc385b5 100644
--- a/libs/hwui/utils/SortedListImpl.h
+++ b/libs/hwui/utils/SortedListImpl.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_UI_SORTED_LIST_IMPL_H
-#define ANDROID_UI_SORTED_LIST_IMPL_H
+#ifndef ANDROID_HWUI_SORTED_LIST_IMPL_H
+#define ANDROID_HWUI_SORTED_LIST_IMPL_H
#include <utils/VectorImpl.h>
@@ -62,4 +62,4 @@
}; // namespace uirenderer
}; // namespace android
-#endif // ANDROID_UI_SORTED_LIST_IMPL_H
+#endif // ANDROID_HWUI_SORTED_LIST_IMPL_H
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index 12db908..1994f6a 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -289,7 +289,7 @@
void flushSpan() {
bool merge = false;
if (tail-head == ssize_t(span.size())) {
- Rect const* p = cur;
+ Rect const* p = span.editArray();
Rect const* q = head;
if (p->top == q->bottom) {
merge = true;
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 8c3efff..3f6b7a2 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -384,7 +384,7 @@
private MyMediaScannerClient mClient = new MyMediaScannerClient();
private boolean isDrmEnabled() {
- String prop = System.getProperty("drm.service.enabled");
+ String prop = SystemProperties.get("drm.service.enabled");
return prop != null && prop.equals("true");
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 2008215..55d69f0 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -423,7 +423,12 @@
*/
public boolean pingSupplicant() {
enforceAccessPermission();
- return mWifiStateMachine.syncPingSupplicant();
+ if (mChannel != null) {
+ return mWifiStateMachine.syncPingSupplicant(mChannel);
+ } else {
+ Slog.e(TAG, "mChannel is not initialized");
+ return false;
+ }
}
/**
@@ -634,7 +639,12 @@
*/
public int addOrUpdateNetwork(WifiConfiguration config) {
enforceChangePermission();
- return mWifiStateMachine.syncAddOrUpdateNetwork(config);
+ if (mChannel != null) {
+ return mWifiStateMachine.syncAddOrUpdateNetwork(mChannel, config);
+ } else {
+ Slog.e(TAG, "mChannel is not initialized");
+ return -1;
+ }
}
/**
@@ -662,7 +672,12 @@
*/
public boolean enableNetwork(int netId, boolean disableOthers) {
enforceChangePermission();
- return mWifiStateMachine.syncEnableNetwork(netId, disableOthers);
+ if (mChannel != null) {
+ return mWifiStateMachine.syncEnableNetwork(mChannel, netId, disableOthers);
+ } else {
+ Slog.e(TAG, "mChannel is not initialized");
+ return false;
+ }
}
/**
@@ -673,7 +688,12 @@
*/
public boolean disableNetwork(int netId) {
enforceChangePermission();
- return mWifiStateMachine.syncDisableNetwork(netId);
+ if (mChannel != null) {
+ return mWifiStateMachine.syncDisableNetwork(mChannel, netId);
+ } else {
+ Slog.e(TAG, "mChannel is not initialized");
+ return false;
+ }
}
/**
@@ -708,7 +728,12 @@
public boolean saveConfiguration() {
boolean result = true;
enforceChangePermission();
- return mWifiStateMachine.syncSaveConfig();
+ if (mChannel != null) {
+ return mWifiStateMachine.syncSaveConfig(mChannel);
+ } else {
+ Slog.e(TAG, "mChannel is not initialized");
+ return false;
+ }
}
/**
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 6bd67cc..3531749 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -279,18 +279,10 @@
private static final int CMD_ENABLE_RSSI_POLL = 82;
/* RSSI poll */
private static final int CMD_RSSI_POLL = 83;
- /* Get current RSSI */
- private static final int CMD_GET_RSSI = 84;
- /* Get approx current RSSI */
- private static final int CMD_GET_RSSI_APPROX = 85;
- /* Get link speed on connection */
- private static final int CMD_GET_LINK_SPEED = 86;
- /* Radio mac address */
- private static final int CMD_GET_MAC_ADDR = 87;
/* Set up packet filtering */
- private static final int CMD_START_PACKET_FILTERING = 88;
+ private static final int CMD_START_PACKET_FILTERING = 84;
/* Clear packet filter */
- private static final int CMD_STOP_PACKET_FILTERING = 89;
+ private static final int CMD_STOP_PACKET_FILTERING = 85;
/* Connect to a specified network (network id
* or WifiConfiguration) This involves increasing
* the priority of the network, enabling the network
@@ -299,21 +291,23 @@
* an existing network. All the networks get enabled
* upon a successful connection or a failure.
*/
- private static final int CMD_CONNECT_NETWORK = 90;
+ private static final int CMD_CONNECT_NETWORK = 86;
/* Save the specified network. This involves adding
* an enabled network (if new) and updating the
* config and issuing a save on supplicant config.
*/
- private static final int CMD_SAVE_NETWORK = 91;
+ private static final int CMD_SAVE_NETWORK = 87;
/* Delete the specified network. This involves
* removing the network and issuing a save on
* supplicant config.
*/
- private static final int CMD_FORGET_NETWORK = 92;
+ private static final int CMD_FORGET_NETWORK = 88;
/* Start Wi-Fi protected setup push button configuration */
- private static final int CMD_START_WPS_PBC = 93;
- /* Start Wi-Fi protected setup pin method configuration */
- private static final int CMD_START_WPS_PIN = 94;
+ private static final int CMD_START_WPS_PBC = 89;
+ /* Start Wi-Fi protected setup pin method configuration with pin obtained from AP */
+ private static final int CMD_START_WPS_PIN_FROM_AP = 90;
+ /* Start Wi-Fi protected setup pin method configuration with pin obtained from device */
+ private static final int CMD_START_WPS_PIN_FROM_DEVICE = 91;
/**
* Interval in milliseconds between polling for connection
* status items that are not sent via asynchronous events.
@@ -334,6 +328,9 @@
/* 2.4GHz allows 802.11B/G operation */
private static final int BAND_2G = 2;
+ private static final int SUCCESS = 1;
+ private static final int FAILURE = -1;
+
/**
* The maximum number of times we will retry a connection to an access point
* for which we have failed in acquiring an IP address from DHCP. A value of
@@ -519,8 +516,11 @@
/**
* TODO: doc
*/
- public boolean syncPingSupplicant() {
- return sendSyncMessage(CMD_PING_SUPPLICANT).boolValue;
+ public boolean syncPingSupplicant(AsyncChannel channel) {
+ Message resultMsg = channel.sendMessageSynchronously(CMD_PING_SUPPLICANT);
+ boolean result = (resultMsg.arg1 != FAILURE);
+ resultMsg.recycle();
+ return result;
}
/**
@@ -698,8 +698,11 @@
*
* @return network id of the new network
*/
- public int syncAddOrUpdateNetwork(WifiConfiguration config) {
- return sendSyncMessage(CMD_ADD_OR_UPDATE_NETWORK, config).intValue;
+ public int syncAddOrUpdateNetwork(AsyncChannel channel, WifiConfiguration config) {
+ Message resultMsg = channel.sendMessageSynchronously(CMD_ADD_OR_UPDATE_NETWORK, config);
+ int result = resultMsg.arg1;
+ resultMsg.recycle();
+ return result;
}
public List<WifiConfiguration> syncGetConfiguredNetworks() {
@@ -713,39 +716,24 @@
*/
public boolean syncRemoveNetwork(AsyncChannel channel, int networkId) {
Message resultMsg = channel.sendMessageSynchronously(CMD_REMOVE_NETWORK, networkId);
- boolean result = resultMsg.arg1 != 0;
+ boolean result = (resultMsg.arg1 != FAILURE);
resultMsg.recycle();
return result;
}
/**
- * Return the result of a removeNetwork
- *
- * @param srcMsg is the original message
- * @param result is true if successfully removed
- */
- private void removeNetworkReply(Message srcMsg, boolean result) {
- mReplyChannel.replyToMessage(srcMsg, CMD_REMOVE_NETWORK, result ? 1 : 0);
- }
-
- private class EnableNetParams {
- private int netId;
- private boolean disableOthers;
- EnableNetParams(int n, boolean b) {
- netId = n;
- disableOthers = b;
- }
- }
- /**
* Enable a network
*
* @param netId network id of the network
* @param disableOthers true, if all other networks have to be disabled
* @return {@code true} if the operation succeeds, {@code false} otherwise
*/
- public boolean syncEnableNetwork(int netId, boolean disableOthers) {
- return sendSyncMessage(CMD_ENABLE_NETWORK,
- new EnableNetParams(netId, disableOthers)).boolValue;
+ public boolean syncEnableNetwork(AsyncChannel channel, int netId, boolean disableOthers) {
+ Message resultMsg = channel.sendMessageSynchronously(CMD_ENABLE_NETWORK, netId,
+ disableOthers ? 1 : 0);
+ boolean result = (resultMsg.arg1 != FAILURE);
+ resultMsg.recycle();
+ return result;
}
/**
@@ -754,8 +742,11 @@
* @param netId network id of the network
* @return {@code true} if the operation succeeds, {@code false} otherwise
*/
- public boolean syncDisableNetwork(int netId) {
- return sendSyncMessage(obtainMessage(CMD_DISABLE_NETWORK, netId, 0)).boolValue;
+ public boolean syncDisableNetwork(AsyncChannel channel, int netId) {
+ Message resultMsg = channel.sendMessageSynchronously(CMD_DISABLE_NETWORK, netId);
+ boolean result = (resultMsg.arg1 != FAILURE);
+ resultMsg.recycle();
+ return result;
}
/**
@@ -801,11 +792,11 @@
}
public void startWpsWithPinFromAccessPoint(String bssid, int apPin) {
- sendMessage(obtainMessage(CMD_START_WPS_PIN, apPin, 0, bssid));
+ sendMessage(obtainMessage(CMD_START_WPS_PIN_FROM_AP, apPin, 0, bssid));
}
public int syncStartWpsWithPinFromDevice(AsyncChannel channel, String bssid) {
- Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN, bssid);
+ Message resultMsg = channel.sendMessageSynchronously(CMD_START_WPS_PIN_FROM_DEVICE, bssid);
int result = resultMsg.arg1;
resultMsg.recycle();
return result;
@@ -814,41 +805,6 @@
public void enableRssiPolling(boolean enabled) {
sendMessage(obtainMessage(CMD_ENABLE_RSSI_POLL, enabled ? 1 : 0, 0));
}
- /**
- * Get RSSI to currently connected network
- *
- * @return RSSI value, -1 on failure
- */
- public int syncGetRssi() {
- return sendSyncMessage(CMD_GET_RSSI).intValue;
- }
-
- /**
- * Get approx RSSI to currently connected network
- *
- * @return RSSI value, -1 on failure
- */
- public int syncGetRssiApprox() {
- return sendSyncMessage(CMD_GET_RSSI_APPROX).intValue;
- }
-
- /**
- * Get link speed to currently connected network
- *
- * @return link speed, -1 on failure
- */
- public int syncGetLinkSpeed() {
- return sendSyncMessage(CMD_GET_LINK_SPEED).intValue;
- }
-
- /**
- * Get MAC address of radio
- *
- * @return MAC address, null on failure
- */
- public String syncGetMacAddress() {
- return sendSyncMessage(CMD_GET_MAC_ADDR).stringValue;
- }
/**
* Start packet filtering
@@ -943,8 +899,11 @@
*
* TODO: deprecate this
*/
- public boolean syncSaveConfig() {
- return sendSyncMessage(CMD_SAVE_CONFIG).boolValue;
+ public boolean syncSaveConfig(AsyncChannel channel) {
+ Message resultMsg = channel.sendMessageSynchronously(CMD_SAVE_CONFIG);
+ boolean result = (resultMsg.arg1 != FAILURE);
+ resultMsg.recycle();
+ return result;
}
/**
@@ -1018,73 +977,6 @@
* Internal private functions
********************************************************/
- class SyncReturn {
- boolean boolValue;
- int intValue;
- String stringValue;
- Object objValue;
- }
-
- class SyncParams {
- Object mParameter;
- SyncReturn mSyncReturn;
- SyncParams() {
- mSyncReturn = new SyncReturn();
- }
- SyncParams(Object p) {
- mParameter = p;
- mSyncReturn = new SyncReturn();
- }
- }
-
- /**
- * message.obj is used to store SyncParams
- */
- private SyncReturn syncedSend(Message msg) {
- SyncParams syncParams = (SyncParams) msg.obj;
- synchronized(syncParams) {
- if (DBG) Log.d(TAG, "syncedSend " + msg);
- sendMessage(msg);
- try {
- syncParams.wait();
- } catch (InterruptedException e) {
- Log.e(TAG, "sendSyncMessage: unexpected interruption of wait()");
- return null;
- }
- }
- return syncParams.mSyncReturn;
- }
-
- private SyncReturn sendSyncMessage(Message msg) {
- SyncParams syncParams = new SyncParams();
- msg.obj = syncParams;
- return syncedSend(msg);
- }
-
- private SyncReturn sendSyncMessage(int what, Object param) {
- SyncParams syncParams = new SyncParams(param);
- Message msg = obtainMessage(what, syncParams);
- return syncedSend(msg);
- }
-
-
- private SyncReturn sendSyncMessage(int what) {
- return sendSyncMessage(obtainMessage(what));
- }
-
- private void notifyOnMsgObject(Message msg) {
- SyncParams syncParams = (SyncParams) msg.obj;
- if (syncParams != null) {
- synchronized(syncParams) {
- if (DBG) Log.d(TAG, "notifyOnMsgObject " + msg);
- syncParams.notify();
- }
- }
- else {
- Log.e(TAG, "Error! syncParams in notifyOnMsgObject is null");
- }
- }
-
private void setWifiState(int wifiState) {
final int previousWifiState = mWifiState.get();
@@ -1620,7 +1512,6 @@
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- SyncParams syncParams;
switch (message.what) {
case CMD_SET_BLUETOOTH_HEADSET_PROXY:
mBluetoothHeadset = (BluetoothHeadset) message.obj;
@@ -1633,19 +1524,10 @@
case CMD_ENABLE_NETWORK:
case CMD_DISABLE_NETWORK:
case CMD_ADD_OR_UPDATE_NETWORK:
- case CMD_GET_RSSI:
- case CMD_GET_RSSI_APPROX:
- case CMD_GET_LINK_SPEED:
- case CMD_GET_MAC_ADDR:
- case CMD_SAVE_CONFIG:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.boolValue = false;
- syncParams.mSyncReturn.intValue = -1;
- syncParams.mSyncReturn.stringValue = null;
- notifyOnMsgObject(message);
- break;
case CMD_REMOVE_NETWORK:
- removeNetworkReply(message, false);
+ case CMD_SAVE_CONFIG:
+ case CMD_START_WPS_PIN_FROM_DEVICE:
+ mReplyChannel.replyToMessage(message, message.what, FAILURE);
break;
case CMD_ENABLE_RSSI_POLL:
mEnableRssiPolling = (message.arg1 == 1);
@@ -1687,7 +1569,7 @@
case CMD_SAVE_NETWORK:
case CMD_FORGET_NETWORK:
case CMD_START_WPS_PBC:
- case CMD_START_WPS_PIN:
+ case CMD_START_WPS_PIN_FROM_AP:
break;
default:
Log.e(TAG, "Error! unhandled message" + message);
@@ -2032,7 +1914,6 @@
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- SyncParams syncParams;
WifiConfiguration config;
switch(message.what) {
case CMD_STOP_SUPPLICANT: /* Supplicant stopped by user */
@@ -2060,36 +1941,29 @@
sendScanResultsAvailableBroadcast();
break;
case CMD_PING_SUPPLICANT:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.boolValue = WifiNative.pingCommand();
- notifyOnMsgObject(message);
+ boolean ok = WifiNative.pingCommand();
+ mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
case CMD_ADD_OR_UPDATE_NETWORK:
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
- syncParams = (SyncParams) message.obj;
- config = (WifiConfiguration) syncParams.mParameter;
- syncParams.mSyncReturn.intValue = WifiConfigStore.addOrUpdateNetwork(config);
- notifyOnMsgObject(message);
+ config = (WifiConfiguration) message.obj;
+ mReplyChannel.replyToMessage(message, CMD_ADD_OR_UPDATE_NETWORK,
+ WifiConfigStore.addOrUpdateNetwork(config));
break;
case CMD_REMOVE_NETWORK:
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
- boolean ok = WifiConfigStore.removeNetwork(message.arg1);
- removeNetworkReply(message, ok);
+ ok = WifiConfigStore.removeNetwork(message.arg1);
+ mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
case CMD_ENABLE_NETWORK:
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
- syncParams = (SyncParams) message.obj;
- EnableNetParams enableNetParams = (EnableNetParams) syncParams.mParameter;
- syncParams.mSyncReturn.boolValue = WifiConfigStore.enableNetwork(
- enableNetParams.netId, enableNetParams.disableOthers);
- notifyOnMsgObject(message);
+ ok = WifiConfigStore.enableNetwork(message.arg1, message.arg2 == 1);
+ mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
case CMD_DISABLE_NETWORK:
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.boolValue = WifiConfigStore.disableNetwork(
- message.arg1);
- notifyOnMsgObject(message);
+ ok = WifiConfigStore.disableNetwork(message.arg1);
+ mReplyChannel.replyToMessage(message, message.what, ok ? SUCCESS : FAILURE);
break;
case CMD_BLACKLIST_NETWORK:
EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
@@ -2099,9 +1973,9 @@
WifiNative.clearBlacklistCommand();
break;
case CMD_SAVE_CONFIG:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.boolValue = WifiConfigStore.saveConfig();
- notifyOnMsgObject(message);
+ ok = WifiConfigStore.saveConfig();
+ mReplyChannel.replyToMessage(message, CMD_SAVE_CONFIG, ok ? SUCCESS : FAILURE);
+
// Inform the backup manager about a data change
IBackupManager ibm = IBackupManager.Stub.asInterface(
ServiceManager.getService(Context.BACKUP_SERVICE));
@@ -2113,11 +1987,6 @@
}
}
break;
- case CMD_GET_MAC_ADDR:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.stringValue = WifiNative.getMacAddressCommand();
- notifyOnMsgObject(message);
- break;
/* Cannot start soft AP while in client mode */
case CMD_START_AP:
Log.d(TAG, "Failed to start soft AP with a running supplicant");
@@ -2207,7 +2076,6 @@
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- SyncParams syncParams;
switch(message.what) {
case CMD_SET_SCAN_TYPE:
if (message.arg1 == SCAN_ACTIVE) {
@@ -2333,7 +2201,6 @@
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- SyncParams syncParams;
switch(message.what) {
case CMD_SET_SCAN_MODE:
if (message.arg1 == SCAN_ONLY_MODE) {
@@ -2374,7 +2241,6 @@
@Override
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
- SyncParams syncParams;
StateChangeResult stateChangeResult;
switch(message.what) {
case PASSWORD_MAY_BE_INCORRECT_EVENT:
@@ -2449,18 +2315,25 @@
transitionTo(mDisconnectingState);
}
break;
- case CMD_START_WPS_PIN:
+ case CMD_START_WPS_PIN_FROM_AP:
bssid = (String) message.obj;
int apPin = message.arg1;
- int pin;
- if (apPin != 0) {
- /* WPS pin from access point */
- success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
- } else {
- pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
- success = (pin != -1);
- mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN, pin);
+
+ /* WPS pin from access point */
+ success = WifiConfigStore.startWpsWithPinFromAccessPoint(bssid, apPin);
+
+ if (success) {
+ mWpsStarted = true;
+ /* Expect a disconnection from the old connection */
+ transitionTo(mDisconnectingState);
}
+ break;
+ case CMD_START_WPS_PIN_FROM_DEVICE:
+ bssid = (String) message.obj;
+ int pin = WifiConfigStore.startWpsWithPinFromDevice(bssid);
+ success = (pin != FAILURE);
+ mReplyChannel.replyToMessage(message, CMD_START_WPS_PIN_FROM_DEVICE, pin);
+
if (success) {
mWpsStarted = true;
/* Expect a disconnection from the old connection */
@@ -2491,21 +2364,6 @@
handleNetworkDisconnect();
transitionTo(mDisconnectedState);
break;
- case CMD_GET_RSSI:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.intValue = WifiNative.getRssiCommand();
- notifyOnMsgObject(message);
- break;
- case CMD_GET_RSSI_APPROX:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.intValue = WifiNative.getRssiApproxCommand();
- notifyOnMsgObject(message);
- break;
- case CMD_GET_LINK_SPEED:
- syncParams = (SyncParams) message.obj;
- syncParams.mSyncReturn.intValue = WifiNative.getLinkSpeedCommand();
- notifyOnMsgObject(message);
- break;
default:
return NOT_HANDLED;
}