Merge "Revert "Use ObjectAnimator for fading scrollbars, set initial duration to 1500""
diff --git a/api/current.txt b/api/current.txt
index 285d75d..e92e9f4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1719,6 +1719,7 @@
field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
+ field public static final int redo = 16908339; // 0x1020033
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1735,6 +1736,7 @@
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
+ field public static final int undo = 16908338; // 0x1020032
field public static final int widget_frame = 16908312; // 0x1020018
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 0393896..29ebf57 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1795,6 +1795,7 @@
field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
+ field public static final int redo = 16908339; // 0x1020033
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1811,6 +1812,7 @@
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
+ field public static final int undo = 16908338; // 0x1020032
field public static final int widget_frame = 16908312; // 0x1020018
}
diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java
index e3bc238..559b01c 100644
--- a/core/java/android/content/UndoManager.java
+++ b/core/java/android/content/UndoManager.java
@@ -105,8 +105,7 @@
return owner;
}
- owner = new UndoOwner(tag);
- owner.mManager = this;
+ owner = new UndoOwner(tag, this);
owner.mData = data;
mOwners.put(tag, owner);
return owner;
@@ -116,7 +115,6 @@
// XXX need to figure out how to prune.
if (false) {
mOwners.remove(owner.mTag);
- owner.mManager = null;
}
}
@@ -202,7 +200,7 @@
UndoOwner owner = mStateOwners[idx];
if (owner == null) {
String tag = in.readString();
- owner = new UndoOwner(tag);
+ owner = new UndoOwner(tag, this);
mStateOwners[idx] = owner;
mOwners.put(tag, owner);
}
diff --git a/core/java/android/content/UndoOwner.java b/core/java/android/content/UndoOwner.java
index d0cdc95..9106588 100644
--- a/core/java/android/content/UndoOwner.java
+++ b/core/java/android/content/UndoOwner.java
@@ -23,8 +23,8 @@
*/
public class UndoOwner {
final String mTag;
+ final UndoManager mManager;
- UndoManager mManager;
Object mData;
int mOpCount;
@@ -32,8 +32,15 @@
int mStateSeq;
int mSavedIdx;
- UndoOwner(String tag) {
+ UndoOwner(String tag, UndoManager manager) {
+ if (tag == null) {
+ throw new NullPointerException("tag can't be null");
+ }
+ if (manager == null) {
+ throw new NullPointerException("manager can't be null");
+ }
mTag = tag;
+ mManager = manager;
}
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 4752594..8601d2b 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -50,6 +50,7 @@
import android.inputmethodservice.ExtractEditText;
import android.os.Bundle;
import android.os.Handler;
+import android.os.ParcelableParcel;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.DynamicLayout;
@@ -118,15 +119,18 @@
*/
public class Editor {
private static final String TAG = "Editor";
- static final boolean DEBUG_UNDO = false;
+ private static final boolean DEBUG_UNDO = false;
static final int BLINK = 500;
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
+ // Tag used when the Editor maintains its own separate UndoManager.
+ private static final String UNDO_OWNER_TAG = "Editor";
- UndoManager mUndoManager;
- UndoOwner mUndoOwner;
- InputFilter mUndoInputFilter;
+ // Each Editor manages its own undo stack.
+ private final UndoManager mUndoManager = new UndoManager();
+ private UndoOwner mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
+ final InputFilter mUndoInputFilter = new UndoInputFilter(this);
// Cursor Controllers.
InsertionPointCursorController mInsertionPointCursorController;
@@ -222,6 +226,39 @@
Editor(TextView textView) {
mTextView = textView;
+ // Synchronize the filter list, which places the undo input filter at the end.
+ mTextView.setFilters(mTextView.getFilters());
+ }
+
+ ParcelableParcel saveInstanceState() {
+ // For now there is only undo state.
+ return (ParcelableParcel) mUndoManager.saveInstanceState();
+ }
+
+ void restoreInstanceState(ParcelableParcel state) {
+ mUndoManager.restoreInstanceState(state);
+ // Re-associate this object as the owner of undo state.
+ mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
+ }
+
+ boolean canUndo() {
+ UndoOwner[] owners = { mUndoOwner };
+ return mUndoManager.countUndos(owners) > 0;
+ }
+
+ boolean canRedo() {
+ UndoOwner[] owners = { mUndoOwner };
+ return mUndoManager.countRedos(owners) > 0;
+ }
+
+ void undo() {
+ UndoOwner[] owners = { mUndoOwner };
+ mUndoManager.undo(owners, 1); // Undo 1 action.
+ }
+
+ void redo() {
+ UndoOwner[] owners = { mUndoOwner };
+ mUndoManager.redo(owners, 1); // Redo 1 action.
}
void onAttachedToWindow() {
@@ -1706,7 +1743,7 @@
/**
* Called by the framework in response to a text auto-correction (such as fixing a typo using a
- * a dictionnary) from the current input method, provided by it calling
+ * a dictionary) from the current input method, provided by it calling
* {@link InputConnection#commitCorrection} InputConnection.commitCorrection()}. The default
* implementation flashes the background of the corrected word to provide feedback to the user.
*
@@ -4161,8 +4198,12 @@
int mChangedStart, mChangedEnd, mChangedDelta;
}
+ /**
+ * An InputFilter that monitors text input to maintain undo history. It does not modify the
+ * text being typed (and hence always returns null from the filter() method).
+ */
public static class UndoInputFilter implements InputFilter {
- final Editor mEditor;
+ private final Editor mEditor;
public UndoInputFilter(Editor editor) {
mEditor = editor;
@@ -4192,6 +4233,8 @@
// The current operation is an add... are we adding more? We are adding
// more if we are either appending new text to the end of the last edit or
// completely replacing some or all of the last edit.
+ // TODO: This sequence doesn't work right: a, left-arrow, b, undo, undo.
+ // The two edits are incorrectly merged, so there is only one undo available.
if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd)
|| (dstart == op.mRangeEnd && dend == op.mRangeEnd))) {
op.mRangeEnd = dstart + (end-start);
@@ -4245,7 +4288,10 @@
}
}
- public static class TextModifyOperation extends UndoOperation<TextView> {
+ /**
+ * An operation to undo a single "edit" to a text view.
+ */
+ public static class TextModifyOperation extends UndoOperation<Editor> {
int mRangeStart, mRangeEnd;
CharSequence mOldText;
@@ -4277,8 +4323,8 @@
private void swapText() {
// Both undo and redo involves swapping the contents of the range
// in the text view with our local text.
- TextView tv = getOwnerData();
- Editable editable = (Editable)tv.getText();
+ Editor editor = getOwnerData();
+ Editable editable = (Editable)editor.mTextView.getText();
CharSequence curText;
if (mRangeStart >= mRangeEnd) {
curText = null;
@@ -4309,14 +4355,17 @@
public static final Parcelable.ClassLoaderCreator<TextModifyOperation> CREATOR
= new Parcelable.ClassLoaderCreator<TextModifyOperation>() {
+ @Override
public TextModifyOperation createFromParcel(Parcel in) {
return new TextModifyOperation(in, null);
}
+ @Override
public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) {
return new TextModifyOperation(in, loader);
}
+ @Override
public TextModifyOperation[] newArray(int size) {
return new TextModifyOperation[size];
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 27603f5..2d0a9cb 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -47,6 +47,7 @@
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.ParcelableParcel;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -1612,7 +1613,8 @@
* @hide
*/
public final UndoManager getUndoManager() {
- return mEditor == null ? null : mEditor.mUndoManager;
+ // TODO: Consider supporting a global undo manager.
+ throw new UnsupportedOperationException("not implemented");
}
/**
@@ -1630,22 +1632,12 @@
* @hide
*/
public final void setUndoManager(UndoManager undoManager, String tag) {
- if (undoManager != null) {
- createEditorIfNeeded();
- mEditor.mUndoManager = undoManager;
- mEditor.mUndoOwner = undoManager.getOwner(tag, this);
- mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor);
- if (!(mText instanceof Editable)) {
- setText(mText, BufferType.EDITABLE);
- }
-
- setFilters((Editable) mText, mFilters);
- } else if (mEditor != null) {
- // XXX need to destroy all associated state.
- mEditor.mUndoManager = null;
- mEditor.mUndoOwner = null;
- mEditor.mUndoInputFilter = null;
- }
+ // TODO: Consider supporting a global undo manager. An implementation will need to:
+ // * createEditorIfNeeded()
+ // * Promote to BufferType.EDITABLE if needed.
+ // * Update the UndoManager and UndoOwner.
+ // Likewise it will need to be able to restore the default UndoManager.
+ throw new UnsupportedOperationException("not implemented");
}
/**
@@ -3899,6 +3891,9 @@
ss.error = getError();
+ if (mEditor != null) {
+ ss.editorState = mEditor.saveInstanceState();
+ }
return ss;
}
@@ -3968,6 +3963,11 @@
}
});
}
+
+ if (ss.editorState != null) {
+ createEditorIfNeeded();
+ mEditor.restoreInstanceState(ss.editorState);
+ }
}
/**
@@ -8383,6 +8383,11 @@
return onTextContextMenuItem(ID_SELECT_ALL);
}
break;
+ case KeyEvent.KEYCODE_Z:
+ if (canUndo()) {
+ return onTextContextMenuItem(ID_UNDO);
+ }
+ break;
case KeyEvent.KEYCODE_X:
if (canCut()) {
return onTextContextMenuItem(ID_CUT);
@@ -8402,11 +8407,15 @@
} else if (event.hasModifiers(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)) {
// Handle Ctrl-Shift shortcuts.
switch (keyCode) {
+ case KeyEvent.KEYCODE_Z:
+ if (canRedo()) {
+ return onTextContextMenuItem(ID_REDO);
+ }
+ break;
case KeyEvent.KEYCODE_V:
if (canPaste()) {
return onTextContextMenuItem(ID_PASTE_AS_PLAIN_TEXT);
}
- break;
}
}
return super.onKeyShortcut(keyCode, event);
@@ -8784,6 +8793,8 @@
}
static final int ID_SELECT_ALL = android.R.id.selectAll;
+ static final int ID_UNDO = android.R.id.undo;
+ static final int ID_REDO = android.R.id.redo;
static final int ID_CUT = android.R.id.cut;
static final int ID_COPY = android.R.id.copy;
static final int ID_PASTE = android.R.id.paste;
@@ -8815,6 +8826,18 @@
selectAllText();
return true;
+ case ID_UNDO:
+ if (mEditor != null) {
+ mEditor.undo();
+ }
+ return true; // Returns true even if nothing was undone.
+
+ case ID_REDO:
+ if (mEditor != null) {
+ mEditor.redo();
+ }
+ return true; // Returns true even if nothing was undone.
+
case ID_PASTE:
paste(min, max, true /* withFormatting */);
return true;
@@ -8948,7 +8971,17 @@
* @hide
*/
protected void stopSelectionActionMode() {
- mEditor.stopSelectionActionMode();
+ if (mEditor != null) {
+ mEditor.stopSelectionActionMode();
+ }
+ }
+
+ boolean canUndo() {
+ return mEditor != null && mEditor.canUndo();
+ }
+
+ boolean canRedo() {
+ return mEditor != null && mEditor.canRedo();
}
boolean canCut() {
@@ -9325,6 +9358,7 @@
CharSequence text;
boolean frozenWithFocus;
CharSequence error;
+ ParcelableParcel editorState; // Optional state from Editor.
SavedState(Parcelable superState) {
super(superState);
@@ -9344,6 +9378,13 @@
out.writeInt(1);
TextUtils.writeToParcel(error, out, flags);
}
+
+ if (editorState == null) {
+ out.writeInt(0);
+ } else {
+ out.writeInt(1);
+ editorState.writeToParcel(out, flags);
+ }
}
@Override
@@ -9379,6 +9420,10 @@
if (in.readInt() != 0) {
error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
}
+
+ if (in.readInt() != 0) {
+ editorState = ParcelableParcel.CREATOR.createFromParcel(in);
+ }
}
}
diff --git a/core/java/android/alsa/AlsaCardsParser.java b/core/java/com/android/internal/alsa/AlsaCardsParser.java
similarity index 99%
rename from core/java/android/alsa/AlsaCardsParser.java
rename to core/java/com/android/internal/alsa/AlsaCardsParser.java
index 5e88bca..5c0a888 100644
--- a/core/java/android/alsa/AlsaCardsParser.java
+++ b/core/java/com/android/internal/alsa/AlsaCardsParser.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
import android.util.Slog;
import java.io.BufferedReader;
diff --git a/core/java/android/alsa/AlsaDevicesParser.java b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
similarity index 99%
rename from core/java/android/alsa/AlsaDevicesParser.java
rename to core/java/com/android/internal/alsa/AlsaDevicesParser.java
index b140d3d..81b7943 100644
--- a/core/java/android/alsa/AlsaDevicesParser.java
+++ b/core/java/com/android/internal/alsa/AlsaDevicesParser.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
import android.util.Slog;
import java.io.BufferedReader;
diff --git a/core/java/android/alsa/LineTokenizer.java b/core/java/com/android/internal/alsa/LineTokenizer.java
similarity index 97%
rename from core/java/android/alsa/LineTokenizer.java
rename to core/java/com/android/internal/alsa/LineTokenizer.java
index 78c91b5..43047a9 100644
--- a/core/java/android/alsa/LineTokenizer.java
+++ b/core/java/com/android/internal/alsa/LineTokenizer.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.alsa;
+package com.android.internal.alsa;
/**
* @hide
diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp
index 6c95b8a..5cb8b2e 100644
--- a/core/jni/android_util_EventLog.cpp
+++ b/core/jni/android_util_EventLog.cpp
@@ -188,6 +188,10 @@
break;
}
+ if (log_msg.id() != LOG_ID_EVENTS) {
+ continue;
+ }
+
int32_t tag = * (int32_t *) log_msg.msg();
int found = 0;
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 6e2f534..d657bad 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -90,4 +90,6 @@
<item type="id" name="statusBarBackground" />
<item type="id" name="navigationBarBackground" />
<item type="id" name="pasteAsPlainText" />
+ <item type="id" name="undo" />
+ <item type="id" name="redo" />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2869091..37f8232 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2645,5 +2645,9 @@
<!-- Context menu ID for the "Paste as plain text" menu item to to copy the current contents
of the clipboard into the text view without formatting. -->
<public type="id" name="pasteAsPlainText" />
-
+ <!-- Context menu ID for the "Undo" menu item to undo the last text edit operation. -->
+ <public type="id" name="undo" />
+ <!-- Context menu ID for the "Redo" menu item to redo the last text edit operation. -->
+ <public type="id" name="redo" />
+
</resources>
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index c9a5679..62da6e08 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -94,8 +94,10 @@
struct TextureData {
Texture* texture;
+ GLenum target;
GLenum filter;
GLenum clamp;
+ Matrix4* textureTransform;
} texture;
bool colorEnabled;
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index f50dfc8..3108a8d 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -274,7 +274,8 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = { &texture, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE };
+ mOutGlop->fill.texture = { &texture,
+ GL_TEXTURE_2D, PaintUtils::getFilter(paint), GL_CLAMP_TO_EDGE, nullptr };
if (paint) {
int color = paint->getColor();
@@ -315,7 +316,7 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
setFill(paint.getColor(), alphaScale, PaintUtils::getXfermode(paint.getXfermode()),
paint.getShader(), paint.getColorFilter());
@@ -329,7 +330,7 @@
REQUIRE_STAGES(kMeshStage);
//specify invalid filter/clamp, since these are always static for PathTextures
- mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM };
+ mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
setFill(paint.getColor(), alphaScale, PaintUtils::getXfermode(paint.getXfermode()),
paint.getShader(), paint.getColorFilter());
@@ -345,7 +346,7 @@
REQUIRE_STAGES(kMeshStage);
//specify invalid filter/clamp, since these are always static for ShadowTextures
- mOutGlop->fill.texture = { &texture, GL_INVALID_ENUM, GL_INVALID_ENUM };
+ mOutGlop->fill.texture = { &texture, GL_TEXTURE_2D, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
const int ALPHA_BITMASK = SK_ColorBLACK;
const int COLOR_BITMASK = ~ALPHA_BITMASK;
@@ -366,7 +367,7 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
setFill(SK_ColorBLACK, 1.0f, SkXfermode::kSrcOver_Mode, nullptr, nullptr);
return *this;
}
@@ -375,7 +376,7 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM };
+ mOutGlop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr };
setFill(SK_ColorBLACK, 1.0f, SkXfermode::kClear_Mode, nullptr, nullptr);
return *this;
}
@@ -385,7 +386,8 @@
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage);
- mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE };
+ mOutGlop->fill.texture = { &texture,
+ GL_TEXTURE_2D, GL_LINEAR, GL_CLAMP_TO_EDGE, nullptr };
mOutGlop->fill.color = { alpha, alpha, alpha, alpha };
setFill(SK_ColorWHITE, alpha, mode, nullptr, colorFilter);
@@ -394,6 +396,21 @@
return *this;
}
+GlopBuilder& GlopBuilder::setFillTextureLayer(Layer& layer, float alpha) {
+ TRIGGER_STAGE(kFillStage);
+ REQUIRE_STAGES(kMeshStage);
+
+ mOutGlop->fill.texture = { &(layer.getTexture()),
+ layer.getRenderTarget(), GL_LINEAR, GL_CLAMP_TO_EDGE, &layer.getTexTransform() };
+ mOutGlop->fill.color = { alpha, alpha, alpha, alpha };
+
+ setFill(SK_ColorWHITE, alpha, layer.getMode(), nullptr, layer.getColorFilter());
+
+ mDescription.modulate = mOutGlop->fill.color.a < 1.0f;
+ mDescription.hasTextureTransform = true;
+ return *this;
+}
+
////////////////////////////////////////////////////////////////////////////////
// Transform
////////////////////////////////////////////////////////////////////////////////
@@ -492,20 +509,27 @@
void verify(const ProgramDescription& description, const Glop& glop) {
bool hasTexture = glop.fill.texture.texture != nullptr;
- LOG_ALWAYS_FATAL_IF(description.hasTexture != hasTexture);
+ LOG_ALWAYS_FATAL_IF(description.hasTexture && description.hasExternalTexture);
+ LOG_ALWAYS_FATAL_IF((description.hasTexture || description.hasExternalTexture )!= hasTexture);
LOG_ALWAYS_FATAL_IF((glop.mesh.vertices.flags & VertexAttribFlags::kTextureCoord) != hasTexture);
if ((glop.mesh.vertices.flags & VertexAttribFlags::kAlpha) && glop.mesh.vertices.bufferObject) {
LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible");
}
+
+ if (description.hasTextureTransform != (glop.fill.texture.textureTransform != nullptr)) {
+ LOG_ALWAYS_FATAL("Texture transform incorrectly specified");
+ }
}
void GlopBuilder::build() {
REQUIRE_STAGES(kAllStages);
-
- mDescription.hasTexture = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kTextureCoord);
- mDescription.hasColors = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kColor);
- mDescription.hasVertexAlpha = static_cast<int>(mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha);
+ if (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kTextureCoord) {
+ mDescription.hasTexture = mOutGlop->fill.texture.target == GL_TEXTURE_2D;
+ mDescription.hasExternalTexture = mOutGlop->fill.texture.target == GL_TEXTURE_EXTERNAL_OES;
+ }
+ mDescription.hasColors = mOutGlop->mesh.vertices.flags & VertexAttribFlags::kColor;
+ mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha;
// serialize shader info into ShaderData
GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index c24b122..4b871d5 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -57,11 +57,19 @@
GlopBuilder& setFillClear();
GlopBuilder& setFillLayer(Texture& texture, const SkColorFilter* colorFilter,
float alpha, SkXfermode::Mode mode);
+ GlopBuilder& setFillTextureLayer(Layer& layer, float alpha);
GlopBuilder& setTransform(const Matrix4& ortho, const Matrix4& transform, bool fudgingOffset);
GlopBuilder& setModelViewMapUnitToRect(const Rect destination);
GlopBuilder& setModelViewMapUnitToRectSnap(const Rect destination);
+ GlopBuilder& setModelViewMapUnitToRectOptionalSnap(bool snap, const Rect destination) {
+ if (snap) {
+ return setModelViewMapUnitToRectSnap(destination);
+ } else {
+ return setModelViewMapUnitToRect(destination);
+ }
+ }
GlopBuilder& setModelViewOffsetRect(float offsetX, float offsetY, const Rect source);
GlopBuilder& setModelViewOffsetRectSnap(float offsetX, float offsetY, const Rect source);
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index f598664..30ffcea 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -356,8 +356,9 @@
bool LayerRenderer::copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap) {
Caches& caches = Caches::getInstance();
- if (layer && bitmap->width() <= caches.maxTextureSize &&
- bitmap->height() <= caches.maxTextureSize) {
+ if (layer
+ && bitmap->width() <= caches.maxTextureSize
+ && bitmap->height() <= caches.maxTextureSize) {
GLuint fbo = caches.fboCache.get();
if (!fbo) {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 3913ee5..83715ba 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -846,8 +846,21 @@
}
void OpenGLRenderer::drawTextureLayer(Layer* layer, const Rect& rect) {
- float alpha = getLayerAlpha(layer);
+ if (USE_GLOPS) {
+ bool snap = !layer->getForceFilter()
+ && layer->getWidth() == (uint32_t) rect.getWidth()
+ && layer->getHeight() == (uint32_t) rect.getHeight();
+ Glop glop;
+ GlopBuilder aBuilder(mRenderState, mCaches, &glop);
+ aBuilder.setMeshTexturedUvQuad(nullptr, Rect(0, 1, 1, 0)) // TODO: simplify with VBO
+ .setFillTextureLayer(*layer, getLayerAlpha(layer))
+ .setTransform(currentSnapshot()->getOrthoMatrix(), *currentTransform(), false)
+ .setModelViewMapUnitToRectOptionalSnap(snap, rect)
+ .setRoundRectClipState(currentSnapshot()->roundRectClipState)
+ .build();
+ }
+ float alpha = getLayerAlpha(layer);
setupDraw();
if (layer->getRenderTarget() == GL_TEXTURE_2D) {
setupDrawWithTexture();
@@ -866,10 +879,10 @@
} else {
setupDrawExternalTexture(layer->getTextureId());
}
- if (currentTransform()->isPureTranslate() &&
- !layer->getForceFilter() &&
- layer->getWidth() == (uint32_t) rect.getWidth() &&
- layer->getHeight() == (uint32_t) rect.getHeight()) {
+ if (currentTransform()->isPureTranslate()
+ && !layer->getForceFilter()
+ && layer->getWidth() == (uint32_t) rect.getWidth()
+ && layer->getHeight() == (uint32_t) rect.getHeight()) {
const float x = (int) floorf(rect.left + currentTransform()->getTranslateX() + 0.5f);
const float y = (int) floorf(rect.top + currentTransform()->getTranslateY() + 0.5f);
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 7992077..ca3a4c2 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -260,19 +260,25 @@
meshState().bindIndicesBufferInternal(indices.bufferObject);
if (vertices.flags & VertexAttribFlags::kTextureCoord) {
- // fill.texture always takes slot 0, shader samplers increment from there
+ const Glop::Fill::TextureData& texture = fill.texture;
+ // texture always takes slot 0, shader samplers increment from there
mCaches->textureState().activateTexture(0);
- if (fill.texture.clamp != GL_INVALID_ENUM) {
- fill.texture.texture->setWrap(fill.texture.clamp, true);
+ if (texture.clamp != GL_INVALID_ENUM) {
+ texture.texture->setWrap(texture.clamp, true);
}
- if (fill.texture.filter != GL_INVALID_ENUM) {
- fill.texture.texture->setFilter(fill.texture.filter, true);
+ if (texture.filter != GL_INVALID_ENUM) {
+ texture.texture->setFilter(texture.filter, true);
}
- mCaches->textureState().bindTexture(fill.texture.texture->id);
+ mCaches->textureState().bindTexture(texture.target, texture.texture->id);
meshState().enableTexCoordsVertexArray();
meshState().bindTexCoordsVertexPointer(force, vertices.texCoord, vertices.stride);
+
+ if (texture.textureTransform) {
+ glUniformMatrix4fv(fill.program->getUniform("mainTextureTransform"), 1,
+ GL_FALSE, &texture.textureTransform->data[0]);
+ }
} else {
meshState().disableTexCoordsVertexArray();
}
diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
index 0aa8862..f869841 100644
--- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java
+++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java
@@ -16,8 +16,6 @@
package com.android.server.usb;
-import android.alsa.AlsaCardsParser;
-import android.alsa.AlsaDevicesParser;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
@@ -37,6 +35,8 @@
import android.provider.Settings;
import android.util.Slog;
+import com.android.internal.alsa.AlsaCardsParser;
+import com.android.internal.alsa.AlsaDevicesParser;
import com.android.server.audio.AudioService;
import libcore.io.IoUtils;