Skip to content

Commit 1b85122

Browse files
Romain GuyAndroid (Google) Code Review
authored andcommitted
Merge "Add API to enable mipmaps on Bitmap Bug #7353771" into jb-mr1-dev
2 parents e13ae64 + 713e1bb commit 1b85122

File tree

10 files changed

+173
-5
lines changed

10 files changed

+173
-5
lines changed

api/current.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8263,6 +8263,7 @@ package android.graphics {
82638263
method public int getScaledWidth(int);
82648264
method public final int getWidth();
82658265
method public final boolean hasAlpha();
8266+
method public final boolean hasMipMap();
82668267
method public final boolean isMutable();
82678268
method public final boolean isPremultiplied();
82688269
method public final boolean isRecycled();
@@ -8271,6 +8272,7 @@ package android.graphics {
82718272
method public boolean sameAs(android.graphics.Bitmap);
82728273
method public void setDensity(int);
82738274
method public void setHasAlpha(boolean);
8275+
method public final void setHasMipMap(boolean);
82748276
method public void setPixel(int, int, int);
82758277
method public void setPixels(int[], int, int, int, int, int, int);
82768278
method public void writeToParcel(android.os.Parcel, int);

core/jni/android/graphics/Bitmap.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "SkUnPreMultiply.h"
88

99
#include <binder/Parcel.h>
10-
#include "android_os_Parcel.h"
10+
#include "android_os_Parcel.h"
1111
#include "android_util_Binder.h"
1212
#include "android_nio_utils.h"
1313
#include "CreateJavaOutputStreamAdaptor.h"
@@ -353,6 +353,15 @@ static void Bitmap_setHasAlpha(JNIEnv* env, jobject, SkBitmap* bitmap,
353353
bitmap->setIsOpaque(!hasAlpha);
354354
}
355355

356+
static jboolean Bitmap_hasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap) {
357+
return bitmap->hasHardwareMipMap();
358+
}
359+
360+
static void Bitmap_setHasMipMap(JNIEnv* env, jobject, SkBitmap* bitmap,
361+
jboolean hasMipMap) {
362+
bitmap->setHasHardwareMipMap(hasMipMap);
363+
}
364+
356365
///////////////////////////////////////////////////////////////////////////////
357366

358367
static jobject Bitmap_createFromParcel(JNIEnv* env, jobject, jobject parcel) {
@@ -666,6 +675,8 @@ static JNINativeMethod gBitmapMethods[] = {
666675
{ "nativeConfig", "(I)I", (void*)Bitmap_config },
667676
{ "nativeHasAlpha", "(I)Z", (void*)Bitmap_hasAlpha },
668677
{ "nativeSetHasAlpha", "(IZ)V", (void*)Bitmap_setHasAlpha },
678+
{ "nativeHasMipMap", "(I)Z", (void*)Bitmap_hasMipMap },
679+
{ "nativeSetHasMipMap", "(IZ)V", (void*)Bitmap_setHasMipMap },
669680
{ "nativeCreateFromParcel",
670681
"(Landroid/os/Parcel;)Landroid/graphics/Bitmap;",
671682
(void*)Bitmap_createFromParcel },

graphics/java/android/graphics/Bitmap.java

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,51 @@ public void setHasAlpha(boolean hasAlpha) {
10291029
nativeSetHasAlpha(mNativeBitmap, hasAlpha);
10301030
}
10311031

1032+
/**
1033+
* Indicates whether the renderer responsible for drawing this
1034+
* bitmap should attempt to use mipmaps when this bitmap is drawn
1035+
* scaled down.
1036+
*
1037+
* If you know that you are going to draw this bitmap at less than
1038+
* 50% of its original size, you may be able to obtain a higher
1039+
* quality
1040+
*
1041+
* This property is only a suggestion that can be ignored by the
1042+
* renderer. It is not guaranteed to have any effect.
1043+
*
1044+
* @return true if the renderer should attempt to use mipmaps,
1045+
* false otherwise
1046+
*
1047+
* @see #setHasMipMap(boolean)
1048+
*/
1049+
public final boolean hasMipMap() {
1050+
return nativeHasMipMap(mNativeBitmap);
1051+
}
1052+
1053+
/**
1054+
* Set a hint for the renderer responsible for drawing this bitmap
1055+
* indicating that it should attempt to use mipmaps when this bitmap
1056+
* is drawn scaled down.
1057+
*
1058+
* If you know that you are going to draw this bitmap at less than
1059+
* 50% of its original size, you may be able to obtain a higher
1060+
* quality by turning this property on.
1061+
*
1062+
* Note that if the renderer respects this hint it might have to
1063+
* allocate extra memory to hold the mipmap levels for this bitmap.
1064+
*
1065+
* This property is only a suggestion that can be ignored by the
1066+
* renderer. It is not guaranteed to have any effect.
1067+
*
1068+
* @param hasMipMap indicates whether the renderer should attempt
1069+
* to use mipmaps
1070+
*
1071+
* @see #hasMipMap()
1072+
*/
1073+
public final void setHasMipMap(boolean hasMipMap) {
1074+
nativeSetHasMipMap(mNativeBitmap, hasMipMap);
1075+
}
1076+
10321077
/**
10331078
* Fills the bitmap's pixels with the specified {@link Color}.
10341079
*
@@ -1356,7 +1401,6 @@ private static native boolean nativeCompress(int nativeBitmap, int format,
13561401
private static native int nativeHeight(int nativeBitmap);
13571402
private static native int nativeRowBytes(int nativeBitmap);
13581403
private static native int nativeConfig(int nativeBitmap);
1359-
private static native boolean nativeHasAlpha(int nativeBitmap);
13601404

13611405
private static native int nativeGetPixel(int nativeBitmap, int x, int y);
13621406
private static native void nativeGetPixels(int nativeBitmap, int[] pixels,
@@ -1385,7 +1429,10 @@ private static native Bitmap nativeExtractAlpha(int nativeBitmap,
13851429
int[] offsetXY);
13861430

13871431
private static native void nativePrepareToDraw(int nativeBitmap);
1432+
private static native boolean nativeHasAlpha(int nativeBitmap);
13881433
private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
1434+
private static native boolean nativeHasMipMap(int nativeBitmap);
1435+
private static native void nativeSetHasMipMap(int nBitmap, boolean hasMipMap);
13891436
private static native boolean nativeSameAs(int nb0, int nb1);
13901437

13911438
/* package */ final int ni() {

libs/hwui/OpenGLRenderer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ namespace uirenderer {
4949

5050
#define ALPHA_THRESHOLD 0
5151

52-
#define FILTER(paint) (paint && paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
52+
#define FILTER(paint) (!paint || paint->isFilterBitmap() ? GL_LINEAR : GL_NEAREST)
5353

5454
///////////////////////////////////////////////////////////////////////////////
5555
// Globals

libs/hwui/Texture.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ struct Texture {
3636
minFilter = GL_NEAREST;
3737
magFilter = GL_NEAREST;
3838

39+
mipMap = false;
40+
3941
firstFilter = true;
4042
firstWrap = true;
4143

@@ -83,6 +85,8 @@ struct Texture {
8385
glBindTexture(renderTarget, id);
8486
}
8587

88+
if (mipMap && min == GL_LINEAR) min = GL_LINEAR_MIPMAP_LINEAR;
89+
8690
glTexParameteri(renderTarget, GL_TEXTURE_MIN_FILTER, min);
8791
glTexParameteri(renderTarget, GL_TEXTURE_MAG_FILTER, mag);
8892
}
@@ -116,7 +120,12 @@ struct Texture {
116120
* Optional, size of the original bitmap.
117121
*/
118122
uint32_t bitmapSize;
123+
/**
124+
* Indicates whether this texture will use trilinear filtering.
125+
*/
126+
bool mipMap;
119127

128+
private:
120129
/**
121130
* Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE.
122131
*/
@@ -129,7 +138,6 @@ struct Texture {
129138
GLenum minFilter;
130139
GLenum magFilter;
131140

132-
private:
133141
bool firstFilter;
134142
bool firstWrap;
135143
}; // struct Texture

libs/hwui/TextureCache.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include <utils/threads.h>
2424

25+
#include "Caches.h"
2526
#include "TextureCache.h"
2627
#include "Properties.h"
2728

@@ -73,6 +74,8 @@ void TextureCache::init() {
7374
INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
7475

7576
mDebugEnabled = readDebugLevel() & kDebugCaches;
77+
78+
mHasNPot = Caches::getInstance().extensions.hasNPot();
7679
}
7780

7881
///////////////////////////////////////////////////////////////////////////////
@@ -216,8 +219,11 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
216219
return;
217220
}
218221

222+
// If the texture had mipmap enabled but not anymore,
223+
// force a glTexImage2D to discard the mipmap levels
219224
const bool resize = !regenerate || bitmap->width() != int(texture->width) ||
220-
bitmap->height() != int(texture->height);
225+
bitmap->height() != int(texture->height) ||
226+
(regenerate && mHasNPot && texture->mipMap && !bitmap->hasHardwareMipMap());
221227

222228
if (!regenerate) {
223229
glGenTextures(1, &texture->id);
@@ -261,6 +267,13 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege
261267
break;
262268
}
263269

270+
if (mHasNPot) {
271+
texture->mipMap = bitmap->hasHardwareMipMap();
272+
if (texture->mipMap) {
273+
glGenerateMipmap(GL_TEXTURE_2D);
274+
}
275+
}
276+
264277
if (!regenerate) {
265278
texture->setFilter(GL_NEAREST);
266279
texture->setWrap(GL_CLAMP_TO_EDGE);

libs/hwui/TextureCache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> {
138138

139139
float mFlushRate;
140140

141+
bool mHasNPot;
141142
bool mDebugEnabled;
142143

143144
Vector<SkBitmap*> mGarbage;

tests/HwAccelerationTest/AndroidManifest.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@
3232

3333
<meta-data android:name="android.graphics.renderThread" android:value="true" />
3434

35+
<activity
36+
android:name="MipMapActivity"
37+
android:label="_MipMap">
38+
<intent-filter>
39+
<action android:name="android.intent.action.MAIN" />
40+
<category android:name="android.intent.category.LAUNCHER" />
41+
</intent-filter>
42+
</activity>
43+
3544
<activity
3645
android:name="PathOffsetActivity"
3746
android:label="_PathOffset">
1.7 MB
Loading
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (C) 2010 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.android.test.hwui;
18+
19+
import android.app.Activity;
20+
import android.content.Context;
21+
import android.graphics.Bitmap;
22+
import android.graphics.BitmapFactory;
23+
import android.graphics.Canvas;
24+
import android.graphics.Paint;
25+
import android.graphics.PorterDuff;
26+
import android.graphics.PorterDuffXfermode;
27+
import android.os.Bundle;
28+
import android.util.Log;
29+
import android.view.Gravity;
30+
import android.view.View;
31+
import android.view.animation.Animation;
32+
import android.view.animation.ScaleAnimation;
33+
import android.widget.FrameLayout;
34+
35+
@SuppressWarnings({"UnusedDeclaration"})
36+
public class MipMapActivity extends Activity {
37+
@Override
38+
protected void onCreate(Bundle savedInstanceState) {
39+
super.onCreate(savedInstanceState);
40+
final BitmapsView view = new BitmapsView(this);
41+
setContentView(view);
42+
}
43+
44+
static class BitmapsView extends View {
45+
private Paint mBitmapPaint;
46+
private final Bitmap mBitmap1;
47+
private final Bitmap mBitmap2;
48+
49+
BitmapsView(Context c) {
50+
super(c);
51+
52+
mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
53+
mBitmap2 = BitmapFactory.decodeResource(c.getResources(), R.drawable.very_large_photo);
54+
55+
mBitmap1.setHasMipMap(true);
56+
57+
mBitmapPaint = new Paint();
58+
mBitmapPaint.setFilterBitmap(true);
59+
}
60+
61+
@Override
62+
protected void onDraw(Canvas canvas) {
63+
super.onDraw(canvas);
64+
65+
canvas.save();
66+
canvas.scale(0.3f, 0.3f);
67+
canvas.drawBitmap(mBitmap1, 0, 0, mBitmapPaint);
68+
canvas.restore();
69+
70+
canvas.save();
71+
canvas.translate(mBitmap1.getWidth() * 0.3f + 96.0f, 0.0f);
72+
canvas.scale(0.3f, 0.3f);
73+
canvas.drawBitmap(mBitmap2, 0, 0, mBitmapPaint);
74+
canvas.restore();
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)