summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--core/jni/android/graphics/Bitmap.cpp13
-rw-r--r--graphics/java/android/graphics/Bitmap.java49
-rw-r--r--libs/hwui/OpenGLRenderer.cpp2
-rw-r--r--libs/hwui/Texture.h10
-rw-r--r--libs/hwui/TextureCache.cpp15
-rw-r--r--libs/hwui/TextureCache.h1
-rw-r--r--tests/HwAccelerationTest/AndroidManifest.xml9
-rw-r--r--tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpgbin0 -> 1781694 bytes
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java77
10 files changed, 173 insertions, 5 deletions
diff --git a/api/current.txt b/api/current.txt
index ee9a973..c45706e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8263,6 +8263,7 @@ package android.graphics {
method public int getScaledWidth(int);
method public final int getWidth();
method public final boolean hasAlpha();
+ method public final boolean hasMipMap();
method public final boolean isMutable();
method public final boolean isPremultiplied();
method public final boolean isRecycled();
@@ -8271,6 +8272,7 @@ package android.graphics {
method public boolean sameAs(android.graphics.Bitmap);
method public void setDensity(int);
method public void setHasAlpha(boolean);
+ method public final void setHasMipMap(boolean);
method public void setPixel(int, int, int);
method public void setPixels(int[], int, int, int, int, int, int);
method public void writeToParcel(android.os.Parcel, int);
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index fd7a6a7..f485e03 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -7,7 +7,7 @@
#include "SkUnPreMultiply.h"
#include <binder/Parcel.h>
-#include "android_os_Parcel.h"
+#include "android_os_Parcel.h"
#include "android_util_Binder.h"
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
@@ -353,6 +353,15 @@ static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap,
bitmap->setIsOpaque(!hasAlpha);
}
+static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
+ return bitmap->hasHardwareMipMap();
+}
+
+static void Bitmap_setHasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap,
+ jboolean hasMipMap) {
+ bitmap->setHasHardwareMipMap(hasMipMap);
+}
+
///////////////////////////////////////////////////////////////////////////////
static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
@@ -666,6 +675,8 @@ static JNINativeMethod gBitmapMethods[] = {
{ "nativeConfig", "(I)I", (void*)Bitmap_config },
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
{ "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
+ { "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
+ { "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
{ "nativeCreateFromParcel",
"(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
(void*)Bitmap_createFromParcel },
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 6238edb..22ecc61 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1030,6 +1030,51 @@ public final class Bitmap implements Parcelable {
}
/**
+ * Indicates whether the renderer responsible for drawing this
+ * bitmap should attempt to use mipmaps when this bitmap is drawn
+ * scaled down.
+ *
+ * If you know that you are going to draw this bitmap at less than
+ * 50% of its original size, you may be able to obtain a higher
+ * quality
+ *
+ * This property is only a suggestion that can be ignored by the
+ * renderer. It is not guaranteed to have any effect.
+ *
+ * @return true if the renderer should attempt to use mipmaps,
+ * false otherwise
+ *
+ * @see #setHasMipMap(boolean)
+ */
+ public final boolean hasMipMap() {
+ return nativeHasMipMap(mNativeBitmap);
+ }
+
+ /**
+ * Set a hint for the renderer responsible for drawing this bitmap
+ * indicating that it should attempt to use mipmaps when this bitmap
+ * is drawn scaled down.
+ *
+ * If you know that you are going to draw this bitmap at less than
+ * 50% of its original size, you may be able to obtain a higher
+ * quality by turning this property on.
+ *
+ * Note that if the renderer respects this hint it might have to
+ * allocate extra memory to hold the mipmap levels for this bitmap.
+ *
+ * This property is only a suggestion that can be ignored by the
+ * renderer. It is not guaranteed to have any effect.
+ *
+ * @param hasMipMap indicates whether the renderer should attempt
+ * to use mipmaps
+ *
+ * @see #hasMipMap()
+ */
+ public final void setHasMipMap(boolean hasMipMap) {
+ nativeSetHasMipMap(mNativeBitmap, hasMipMap);
+ }
+
+ /**
* Fills the bitmap's pixels with the specified {@link Color}.
*
* @throws IllegalStateException if the bitmap is not mutable.
@@ -1356,7 +1401,6 @@ public final class Bitmap implements Parcelable {
private static native int nativeHeight(int nativeBitmap);
private static native int nativeRowBytes(int nativeBitmap);
private static native int nativeConfig(int nativeBitmap);
- private static native boolean nativeHasAlpha(int nativeBitmap);
private static native int nativeGetPixel(int nativeBitmap, int x, int y);
private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
@@ -1385,7 +1429,10 @@ public final class Bitmap implements Parcelable {
int[] offsetXY);
private static native void nativePrepareToDraw(int nativeBitmap);
+ private static native boolean nativeHasAlpha(int nativeBitmap);
private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
+ private static native boolean nativeHasMipMap(int nativeBitmap);
+ private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap);
private static native boolean nativeSameAs(int nb0, int nb1);
/* package */ final int ni() {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 89cefe0..406d5e9 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -49,7 +49,7 @@ namespace uirenderer {
#define ALPHA_THRESHOLD 0
-#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
+#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
///////////////////////////////////////////////////////////////////////////////
// Globals
diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h
index 03e2172..8d88bdc 100644
--- a/libs/hwui/Texture.h
+++ b/libs/hwui/Texture.h
@@ -36,6 +36,8 @@ struct Texture {
minFilter = GL_NEAREST;
magFilter = GL_NEAREST;
+ mipMap = false;
+
firstFilter = true;
firstWrap = true;
@@ -83,6 +85,8 @@ struct Texture {
glBindTexture(renderTarget, id);
}
+ if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
+
glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
}
@@ -116,7 +120,12 @@ struct Texture {
* Optional, size of the original bitmap.
*/
uint32_t bitmapSize;
+ /**
+ * Indicates whether this texture will use trilinear filtering.
+ */
+ bool mipMap;
+private:
/**
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
*/
@@ -129,7 +138,6 @@ struct Texture {
GLenum minFilter;
GLenum magFilter;
-private:
bool firstFilter;
bool firstWrap;
}; // struct Texture
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 4d16bb4..431367a 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -22,6 +22,7 @@
#include <utils/threads.h>
+#include "Caches.h"
#include "TextureCache.h"
#include "Properties.h"
@@ -73,6 +74,8 @@ void TextureCache::init() {
INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
mDebugEnabled = readDebugLevel() & kDebugCaches;
+
+ mHasNPot = Caches::getInstance().extensions.hasNPot();
}
///////////////////////////////////////////////////////////////////////////////
@@ -216,8 +219,11 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
return;
}
+ // If the texture had mipmap enabled but not anymore,
+ // force a glTexImage2D to discard the mipmap levels
const bool resize = !regenerate || bitmap->width() != int(texture->width) ||
- bitmap->height() != int(texture->height);
+ bitmap->height() != int(texture->height) ||
+ (regenerate && mHasNPot && texture->mipMap && !bitmap->hasHardwareMipMap());
if (!regenerate) {
glGenTextures(1, &texture->id);
@@ -261,6 +267,13 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
break;
}
+ if (mHasNPot) {
+ texture->mipMap = bitmap->hasHardwareMipMap();
+ if (texture->mipMap) {
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+ }
+
if (!regenerate) {
texture->setFilter(GL_NEAREST);
texture->setWrap(GL_CLAMP_TO_EDGE);
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 31a2e3d..8e19092 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -138,6 +138,7 @@ private:
float mFlushRate;
+ bool mHasNPot;
bool mDebugEnabled;
Vector<SkBitmap*> mGarbage;
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 4cb409d..9118aea 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -33,6 +33,15 @@
<meta-data android:name="android.graphics.renderThread" android:value="true" />
<activity
+ android:name="MipMapActivity"
+ android:label="_MipMap">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="PathOffsetActivity"
android:label="_PathOffset">
<intent-filter>
diff --git a/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
new file mode 100644
index 0000000..7f047b1
--- /dev/null
+++ b/tests/HwAccelerationTest/res/drawable-nodpi/very_large_photo.jpg
Binary files differ
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java
new file mode 100644
index 0000000..1034649
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MipMapActivity.java
@@ -0,0 +1,77 @@
+/*
+ * 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.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
+import android.widget.FrameLayout;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class MipMapActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final BitmapsView view = new BitmapsView(this);
+ setContentView(view);
+ }
+
+ static class BitmapsView extends View {
+ private Paint mBitmapPaint;
+ private final Bitmap mBitmap1;
+ private final Bitmap mBitmap2;
+
+ BitmapsView(Context c) {
+ super(c);
+
+ mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
+ mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
+
+ mBitmap1.setHasMipMap(true);
+
+ mBitmapPaint = new Paint();
+ mBitmapPaint.setFilterBitmap(true);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.scale(0.3f, 0.3f);
+ canvas.drawBitmap(mBitmap1, 0, 0, mBitmapPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(mBitmap1.getWidth() * 0.3f + 96.0f, 0.0f);
+ canvas.scale(0.3f, 0.3f);
+ canvas.drawBitmap(mBitmap2, 0, 0, mBitmapPaint);
+ canvas.restore();
+ }
+ }
+}