New layers API for Views.
This API can be used to back a view and its children with either a software layer (bitmap) or hardware layer (FBO). Layers have various usages, including color filtering and performance improvements during animations. Change-Id: Ifc3bea847918042730fc5a8c2d4206dd6c9420a3
This commit is contained in:
@@ -5900,6 +5900,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="layerType"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="16843606"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="layout"
|
||||
type="int"
|
||||
transient="false"
|
||||
@@ -213314,6 +213325,17 @@
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getLayerType"
|
||||
return="int"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</method>
|
||||
<method name="getLayoutParams"
|
||||
return="android.view.ViewGroup.LayoutParams"
|
||||
abstract="false"
|
||||
@@ -215816,6 +215838,21 @@
|
||||
<parameter name="keepScreenOn" type="boolean">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setLayerType"
|
||||
return="void"
|
||||
abstract="false"
|
||||
native="false"
|
||||
synchronized="false"
|
||||
static="false"
|
||||
final="false"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
<parameter name="layerType" type="int">
|
||||
</parameter>
|
||||
<parameter name="paint" type="android.graphics.Paint">
|
||||
</parameter>
|
||||
</method>
|
||||
<method name="setLayoutParams"
|
||||
return="void"
|
||||
abstract="false"
|
||||
@@ -216903,6 +216940,39 @@
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="LAYER_TYPE_HARDWARE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="2"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="LAYER_TYPE_NONE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="0"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="LAYER_TYPE_SOFTWARE"
|
||||
type="int"
|
||||
transient="false"
|
||||
volatile="false"
|
||||
value="1"
|
||||
static="true"
|
||||
final="true"
|
||||
deprecated="not deprecated"
|
||||
visibility="public"
|
||||
>
|
||||
</field>
|
||||
<field name="MEASURED_HEIGHT_STATE_SHIFT"
|
||||
type="int"
|
||||
transient="false"
|
||||
|
||||
@@ -127,7 +127,11 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
replaceNativeObject(0);
|
||||
try {
|
||||
replaceNativeObject(0);
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,8 +399,11 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
@Override
|
||||
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
|
||||
int saveFlags) {
|
||||
int nativePaint = paint == null ? 0 : paint.mNativePaint;
|
||||
return nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
|
||||
boolean hasColorFilter = paint != null && setupColorFilter(paint);
|
||||
final int nativePaint = paint == null ? 0 : paint.mNativePaint;
|
||||
int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
|
||||
if (hasColorFilter) nResetModifiers(mRenderer);
|
||||
return count;
|
||||
}
|
||||
|
||||
private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
|
||||
|
||||
@@ -58,7 +58,6 @@ import android.util.PoolableManager;
|
||||
import android.util.Pools;
|
||||
import android.util.SparseArray;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.View.MeasureSpec;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityEventSource;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
@@ -546,6 +545,10 @@ import java.util.WeakHashMap;
|
||||
* subtree rooted by that node. When an animation is started, the framework will
|
||||
* take care of redrawing the appropriate views until the animation completes.
|
||||
* </p>
|
||||
* <p>
|
||||
* Starting with Android 3.0, the preferred way of animating views is to use the
|
||||
* {@link android.animation} package APIs.
|
||||
* </p>
|
||||
*
|
||||
* <a name="Security"></a>
|
||||
* <h3>Security</h3>
|
||||
@@ -569,6 +572,7 @@ import java.util.WeakHashMap;
|
||||
* See also {@link MotionEvent#FLAG_WINDOW_IS_OBSCURED}.
|
||||
* </p>
|
||||
*
|
||||
* @attr ref android.R.styleable#View_alpha
|
||||
* @attr ref android.R.styleable#View_background
|
||||
* @attr ref android.R.styleable#View_clickable
|
||||
* @attr ref android.R.styleable#View_contentDescription
|
||||
@@ -584,6 +588,7 @@ import java.util.WeakHashMap;
|
||||
* @attr ref android.R.styleable#View_focusableInTouchMode
|
||||
* @attr ref android.R.styleable#View_hapticFeedbackEnabled
|
||||
* @attr ref android.R.styleable#View_keepScreenOn
|
||||
* @attr ref android.R.styleable#View_layerType
|
||||
* @attr ref android.R.styleable#View_longClickable
|
||||
* @attr ref android.R.styleable#View_minHeight
|
||||
* @attr ref android.R.styleable#View_minWidth
|
||||
@@ -2151,6 +2156,69 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
*/
|
||||
public static final int SCROLLBAR_POSITION_RIGHT = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the view does not have a layer.
|
||||
*
|
||||
* @see #getLayerType()
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
* @see #LAYER_TYPE_SOFTWARE
|
||||
* @see #LAYER_TYPE_HARDWARE
|
||||
*/
|
||||
public static final int LAYER_TYPE_NONE = 0;
|
||||
|
||||
/**
|
||||
* <p>Indicates that the view has a software layer. A software layer is backed
|
||||
* by a bitmap and causes the view to be rendered using Android's software
|
||||
* rendering pipeline, even if hardware acceleration is enabled.</p>
|
||||
*
|
||||
* <p>Software layers have various usages:</p>
|
||||
* <p>When the application is not using hardware acceleration, a software layer
|
||||
* is useful to apply a specific color filter and/or blending mode and/or
|
||||
* translucency to a view and all its children.</p>
|
||||
* <p>When the application is using hardware acceleration, a software layer
|
||||
* is useful to render drawing primitives not supported by the hardware
|
||||
* accelerated pipeline. It can also be used to cache a complex view tree
|
||||
* into a texture and reduce the complexity of drawing operations. For instance,
|
||||
* when animating a complex view tree with a translation, a software layer can
|
||||
* be used to render the view tree only once.</p>
|
||||
* <p>Software layers should be avoided when the affected view tree updates
|
||||
* often. Every update will require to re-render the software layer, which can
|
||||
* potentially be slow (particularly when hardware acceleration is turned on
|
||||
* since the layer will have to be uploaded into a hardware texture after every
|
||||
* update.)</p>
|
||||
*
|
||||
* @see #getLayerType()
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
* @see #LAYER_TYPE_NONE
|
||||
* @see #LAYER_TYPE_HARDWARE
|
||||
*/
|
||||
public static final int LAYER_TYPE_SOFTWARE = 1;
|
||||
|
||||
/**
|
||||
* <p>Indicates that the view has a hardware layer. A hardware layer is backed
|
||||
* by a hardware specific texture (generally Frame Buffer Objects or FBO on
|
||||
* OpenGL hardware) and causes the view to be rendered using Android's hardware
|
||||
* rendering pipeline, but only if hardware acceleration is turned on for the
|
||||
* view hierarchy. When hardware acceleration is turned off, hardware layers
|
||||
* behave exactly as {@link #LAYER_TYPE_SOFTWARE software layers}.</p>
|
||||
*
|
||||
* <p>A hardware layer is useful to apply a specific color filter and/or
|
||||
* blending mode and/or translucency to a view and all its children.</p>
|
||||
* <p>A hardware layer can also be used to increase the rendering quality when
|
||||
* rotation transformations are applied on a view. It can also be used to
|
||||
* prevent potential clipping issues when applying 3D transforms on a view.</p>
|
||||
*
|
||||
* @see #getLayerType()
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
* @see #LAYER_TYPE_NONE
|
||||
* @see #LAYER_TYPE_SOFTWARE
|
||||
*/
|
||||
public static final int LAYER_TYPE_HARDWARE = 2;
|
||||
|
||||
@ViewDebug.ExportedProperty(category = "drawing")
|
||||
int mLayerType = LAYER_TYPE_NONE;
|
||||
Paint mLayerPaint;
|
||||
|
||||
/**
|
||||
* Simple constructor to use when creating a view from code.
|
||||
*
|
||||
@@ -2489,6 +2557,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
case R.styleable.View_verticalScrollbarPosition:
|
||||
mVerticalScrollbarPosition = a.getInt(attr, SCROLLBAR_POSITION_DEFAULT);
|
||||
break;
|
||||
case R.styleable.View_layerType:
|
||||
setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5763,11 +5834,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
|
||||
* completely transparent and 1 means the view is completely opaque.
|
||||
* <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
|
||||
* completely transparent and 1 means the view is completely opaque.</p>
|
||||
*
|
||||
* <p>If this view overrides {@link #onSetAlpha(int)} to return true, then this view is
|
||||
* responsible for applying the opacity itself. Otherwise, calling this method is
|
||||
* equivalent to calling {@link #setLayerType(int, android.graphics.Paint)} and
|
||||
* setting a hardware layer.</p>
|
||||
*
|
||||
* @param alpha The opacity of the view.
|
||||
*
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
*
|
||||
* @attr ref android.R.styleable#View_alpha
|
||||
*/
|
||||
public void setAlpha(float alpha) {
|
||||
@@ -7746,6 +7824,88 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
return (mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Specifies the type of layer backing this view. The layer can be
|
||||
* {@link #LAYER_TYPE_NONE disabled}, {@link #LAYER_TYPE_SOFTWARE software} or
|
||||
* {@link #LAYER_TYPE_HARDWARE hardware}.</p>
|
||||
*
|
||||
* <p>A layer is associated with an optional {@link android.graphics.Paint}
|
||||
* instance that controls how the layer is composed on screen. The following
|
||||
* properties of the paint are taken into account when composing the layer:</p>
|
||||
* <ul>
|
||||
* <li>{@link android.graphics.Paint#getAlpha() Translucency (alpha)}</li>
|
||||
* <li>{@link android.graphics.Paint#getXfermode() Blending mode}</li>
|
||||
* <li>{@link android.graphics.Paint#getColorFilter() Color filter}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>If this view has an alpha value set to < 1.0 by calling
|
||||
* {@link #setAlpha(float)}, the alpha value of the layer's paint is replaced by
|
||||
* this view's alpha value. Calling {@link #setAlpha(float)} is therefore
|
||||
* equivalent to setting a hardware layer on this view and providing a paint with
|
||||
* the desired alpha value.<p>
|
||||
*
|
||||
* <p>Refer to the documentation of {@link #LAYER_TYPE_NONE disabled},
|
||||
* {@link #LAYER_TYPE_SOFTWARE software} and {@link #LAYER_TYPE_HARDWARE hardware}
|
||||
* for more information on when and how to use layers.</p>
|
||||
*
|
||||
* @param layerType The ype of layer to use with this view, must be one of
|
||||
* {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
|
||||
* {@link #LAYER_TYPE_HARDWARE}
|
||||
* @param paint The paint used to compose the layer. This argument is optional
|
||||
* and can be null. It is ignored when the layer type is
|
||||
* {@link #LAYER_TYPE_NONE}
|
||||
*
|
||||
* @see #getLayerType()
|
||||
* @see #LAYER_TYPE_NONE
|
||||
* @see #LAYER_TYPE_SOFTWARE
|
||||
* @see #LAYER_TYPE_HARDWARE
|
||||
* @see #setAlpha(float)
|
||||
*
|
||||
* @attr ref android.R.styleable#View_layerType
|
||||
*/
|
||||
public void setLayerType(int layerType, Paint paint) {
|
||||
if (layerType < LAYER_TYPE_NONE || layerType > LAYER_TYPE_HARDWARE) {
|
||||
throw new IllegalArgumentException("Layer type can only be one of: LAYER_TYPE_NONE, "
|
||||
+ "LAYER_TYPE_SOFTWARE or LAYER_TYPE_HARDWARE");
|
||||
}
|
||||
|
||||
// Destroy any previous software drawing cache if needed
|
||||
if (mLayerType == LAYER_TYPE_SOFTWARE && layerType != LAYER_TYPE_SOFTWARE) {
|
||||
if (mDrawingCache != null) {
|
||||
mDrawingCache.recycle();
|
||||
mDrawingCache = null;
|
||||
}
|
||||
|
||||
if (mUnscaledDrawingCache != null) {
|
||||
mUnscaledDrawingCache.recycle();
|
||||
mUnscaledDrawingCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
mLayerType = layerType;
|
||||
mLayerPaint = mLayerType == LAYER_TYPE_NONE ? null : paint;
|
||||
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates what type of layer is currently associated with this view. By default
|
||||
* a view does not have a layer, and the layer type is {@link #LAYER_TYPE_NONE}.
|
||||
* Refer to the documentation of {@link #setLayerType(int, android.graphics.Paint)}
|
||||
* for more information on the different types of layers.
|
||||
*
|
||||
* @return {@link #LAYER_TYPE_NONE}, {@link #LAYER_TYPE_SOFTWARE} or
|
||||
* {@link #LAYER_TYPE_HARDWARE}
|
||||
*
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
* @see #LAYER_TYPE_NONE
|
||||
* @see #LAYER_TYPE_SOFTWARE
|
||||
* @see #LAYER_TYPE_HARDWARE
|
||||
*/
|
||||
public int getLayerType() {
|
||||
return mLayerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
|
||||
* to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
|
||||
@@ -7753,12 +7913,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
* the cache is enabled. To benefit from the cache, you must request the drawing cache by
|
||||
* calling {@link #getDrawingCache()} and draw it on screen if the returned bitmap is not
|
||||
* null.</p>
|
||||
*
|
||||
* <p>Enabling the drawing cache is similar to
|
||||
* {@link #setLayerType(int, android.graphics.Paint) setting a layer} when hardware
|
||||
* acceleration is turned off. When hardware acceleration is turned on enabling the
|
||||
* drawing cache has either no effect or the cache used at drawing time is not a bitmap.
|
||||
* This API can however be used to manually generate a bitmap copy of this view.</p>
|
||||
*
|
||||
* @param enabled true to enable the drawing cache, false otherwise
|
||||
*
|
||||
* @see #isDrawingCacheEnabled()
|
||||
* @see #getDrawingCache()
|
||||
* @see #buildDrawingCache()
|
||||
* @see #setLayerType(int, android.graphics.Paint)
|
||||
*/
|
||||
public void setDrawingCacheEnabled(boolean enabled) {
|
||||
setFlags(enabled ? DRAWING_CACHE_ENABLED : 0, DRAWING_CACHE_ENABLED);
|
||||
@@ -8077,7 +8244,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
canvas.translate(-mScrollX, -mScrollY);
|
||||
|
||||
mPrivateFlags |= DRAWN;
|
||||
if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated) {
|
||||
if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
|
||||
mLayerType != LAYER_TYPE_NONE) {
|
||||
mPrivateFlags |= DRAWING_CACHE_VALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -2175,11 +2175,15 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
boolean concatMatrix = false;
|
||||
|
||||
boolean scalingRequired = false;
|
||||
boolean caching = false;
|
||||
boolean caching;
|
||||
final int layerType = child.getLayerType();
|
||||
|
||||
if ((flags & FLAG_CHILDREN_DRAWN_WITH_CACHE) == FLAG_CHILDREN_DRAWN_WITH_CACHE ||
|
||||
(flags & FLAG_ALWAYS_DRAWN_WITH_CACHE) == FLAG_ALWAYS_DRAWN_WITH_CACHE) {
|
||||
caching = true;
|
||||
if (mAttachInfo != null) scalingRequired = mAttachInfo.mScalingRequired;
|
||||
} else {
|
||||
caching = layerType != LAYER_TYPE_NONE;
|
||||
}
|
||||
|
||||
if (a != null) {
|
||||
@@ -2270,9 +2274,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
Bitmap cache = null;
|
||||
if (caching) {
|
||||
if (!canvas.isHardwareAccelerated()) {
|
||||
if (layerType != LAYER_TYPE_NONE) {
|
||||
child.buildDrawingCache(true);
|
||||
}
|
||||
cache = child.getDrawingCache(true);
|
||||
} else {
|
||||
displayList = child.getDisplayList();
|
||||
if (layerType == LAYER_TYPE_SOFTWARE) {
|
||||
child.buildDrawingCache(true);
|
||||
cache = child.getDrawingCache(true);
|
||||
} else {
|
||||
displayList = child.getDisplayList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2290,6 +2302,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
canvas.scale(scale, scale);
|
||||
}
|
||||
}
|
||||
|
||||
boolean layerSaved = false;
|
||||
|
||||
if (transformToApply != null || alpha < 1.0f || !child.hasIdentityMatrix()) {
|
||||
if (transformToApply != null || !childHasIdentityMatrix) {
|
||||
@@ -2331,12 +2345,24 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
final int multipliedAlpha = (int) (255 * alpha);
|
||||
if (!child.onSetAlpha(multipliedAlpha)) {
|
||||
int layerFlags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;
|
||||
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN) {
|
||||
if ((flags & FLAG_CLIP_CHILDREN) == FLAG_CLIP_CHILDREN ||
|
||||
layerType != LAYER_TYPE_NONE) {
|
||||
layerFlags |= Canvas.CLIP_TO_LAYER_SAVE_FLAG;
|
||||
}
|
||||
canvas.saveLayerAlpha(sx, sy, sx + cr - cl, sy + cb - ct, multipliedAlpha,
|
||||
layerFlags);
|
||||
if (layerType != LAYER_TYPE_NONE && child.mLayerPaint != null) {
|
||||
child.mLayerPaint.setAlpha(multipliedAlpha);
|
||||
canvas.saveLayer(sx, sy, sx + cr - cl, sy + cb - ct,
|
||||
child.mLayerPaint, layerFlags);
|
||||
} else {
|
||||
canvas.saveLayerAlpha(sx, sy, sx + cr - cl, sy + cb - ct,
|
||||
multipliedAlpha, layerFlags);
|
||||
}
|
||||
layerSaved = true;
|
||||
} else {
|
||||
// Alpha is handled by the child directly, clobber the layer's alpha
|
||||
if (layerType != LAYER_TYPE_NONE && child.mLayerPaint != null) {
|
||||
child.mLayerPaint.setAlpha(255);
|
||||
}
|
||||
child.mPrivateFlags |= ALPHA_SET;
|
||||
}
|
||||
}
|
||||
@@ -2359,6 +2385,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
}
|
||||
|
||||
if (hasNoCache) {
|
||||
if (!layerSaved && layerType == LAYER_TYPE_HARDWARE) {
|
||||
canvas.saveLayer(sx, sy, sx + cr - cl, sy + cb - ct, child.mLayerPaint,
|
||||
Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG);
|
||||
}
|
||||
if (!hasDisplayList) {
|
||||
// Fast path for layouts with no backgrounds
|
||||
if ((child.mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
|
||||
@@ -2376,13 +2406,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
}
|
||||
} else if (cache != null) {
|
||||
child.mPrivateFlags &= ~DIRTY_MASK;
|
||||
final Paint cachePaint = mCachePaint;
|
||||
if (alpha < 1.0f) {
|
||||
cachePaint.setAlpha((int) (alpha * 255));
|
||||
mGroupFlags |= FLAG_ALPHA_LOWER_THAN_ONE;
|
||||
} else if ((flags & FLAG_ALPHA_LOWER_THAN_ONE) == FLAG_ALPHA_LOWER_THAN_ONE) {
|
||||
cachePaint.setAlpha(255);
|
||||
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
|
||||
Paint cachePaint;
|
||||
|
||||
if (layerType == LAYER_TYPE_NONE || child.mLayerPaint == null) {
|
||||
cachePaint = mCachePaint;
|
||||
if (alpha < 1.0f) {
|
||||
cachePaint.setAlpha((int) (alpha * 255));
|
||||
mGroupFlags |= FLAG_ALPHA_LOWER_THAN_ONE;
|
||||
} else if ((flags & FLAG_ALPHA_LOWER_THAN_ONE) == FLAG_ALPHA_LOWER_THAN_ONE) {
|
||||
cachePaint.setAlpha(255);
|
||||
mGroupFlags &= ~FLAG_ALPHA_LOWER_THAN_ONE;
|
||||
}
|
||||
} else {
|
||||
cachePaint = child.mLayerPaint;
|
||||
if (alpha < 1.0f) {
|
||||
cachePaint.setAlpha((int) (alpha * 255));
|
||||
}
|
||||
}
|
||||
canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint);
|
||||
}
|
||||
|
||||
@@ -1784,6 +1784,22 @@
|
||||
<!-- Place the scroll bar on the right. -->
|
||||
<enum name="right" value="2" />
|
||||
</attr>
|
||||
|
||||
<!-- Specifies the type of layer backing this view. The default value is none.
|
||||
Refer to {@link android.view.View#setLayerType(int, android.graphics.Paint)
|
||||
for more information.-->
|
||||
<attr name="layerType">
|
||||
<!-- Don't use a layer. -->
|
||||
<enum name="none" value="0" />
|
||||
<!-- Use a software layer. Refer to
|
||||
{@link android.view.View#setLayerType(int, android.graphics.Paint) for
|
||||
more information. -->
|
||||
<enum name="software" value="1" />
|
||||
<!-- Use a hardware layer. Refer to
|
||||
{@link android.view.View#setLayerType(int, android.graphics.Paint) for
|
||||
more information. -->
|
||||
<enum name="hardware" value="2" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- Attributes that can be used with a {@link android.view.ViewGroup} or any
|
||||
|
||||
@@ -1420,6 +1420,7 @@
|
||||
<public type="attr" name="editTextColor" />
|
||||
<public type="attr" name="editTextBackground" />
|
||||
<public type="attr" name="horizontalScrollViewStyle" />
|
||||
<public type="attr" name="layerType" />
|
||||
|
||||
<!-- A simple fade-in animation. -->
|
||||
<public type="animator" name="fade_in" id="0x010b0000" />
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <SkXfermode.h>
|
||||
|
||||
#include "Rect.h"
|
||||
#include "SkiaColorFilter.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@@ -93,6 +94,11 @@ struct Layer {
|
||||
* have been drawn.
|
||||
*/
|
||||
Region region;
|
||||
|
||||
/**
|
||||
* Color filter used to draw this layer. Optional.
|
||||
*/
|
||||
SkiaColorFilter* colorFilter;
|
||||
}; // struct Layer
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
@@ -102,6 +102,7 @@ Layer* LayerCache::get(const uint32_t width, const uint32_t height) {
|
||||
layer->blend = true;
|
||||
layer->empty = true;
|
||||
layer->fbo = 0;
|
||||
layer->colorFilter = NULL;
|
||||
|
||||
glGenTextures(1, &layer->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, layer->texture);
|
||||
|
||||
@@ -406,6 +406,7 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top,
|
||||
layer->layer.set(bounds);
|
||||
layer->texCoords.set(0.0f, bounds.getHeight() / float(layer->height),
|
||||
bounds.getWidth() / float(layer->width), 0.0f);
|
||||
layer->colorFilter = mColorFilter;
|
||||
|
||||
// Save the layer in the snapshot
|
||||
snapshot->flags |= Snapshot::kFlagIsLayer;
|
||||
@@ -459,7 +460,6 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, sp<Snapshot> sna
|
||||
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();
|
||||
@@ -544,7 +544,13 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
|
||||
// drawing only the dirty region
|
||||
if (fboLayer) {
|
||||
dirtyLayer(rect.left, rect.top, rect.right, rect.bottom, *previous->transform);
|
||||
if (layer->colorFilter) {
|
||||
setupColorFilter(layer->colorFilter);
|
||||
}
|
||||
composeLayerRegion(layer, rect);
|
||||
if (layer->colorFilter) {
|
||||
resetColorFilter();
|
||||
}
|
||||
} else {
|
||||
dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
|
||||
composeLayerRect(layer, rect, true);
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
android:label="HwUi"
|
||||
android:hardwareAccelerated="true">
|
||||
|
||||
<activity
|
||||
android:name="ViewLayersActivity"
|
||||
android:label="_ViewLayers">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="AlphaLayersActivity"
|
||||
android:label="_αLayers">
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.AdvancedBlendActivity.ShadersView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.AdvancedBlendActivity.ShadersView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.AdvancedGradientsActivity.GradientsView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.AdvancedGradientsActivity.GradientsView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.LayersActivity.LayersView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.LayersActivity.LayersView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.LinesActivity.LinesView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.LinesActivity.LinesView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.NewLayersActivity.LayersView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.NewLayersActivity.LayersView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.PathsActivity.PathsView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.PathsActivity.PathsView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<com.android.test.hwui.ShadersActivity.ShadersView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
</com.android.test.hwui.ShadersActivity.ShadersView>
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
|
||||
40
tests/HwAccelerationTest/res/layout/view_layers.xml
Normal file
40
tests/HwAccelerationTest/res/layout/view_layers.xml
Normal file
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2011 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list1"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list2"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list3"
|
||||
android:layout_width="0dip"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.animation.ObjectAnimator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
public class ViewLayersActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.view_layers);
|
||||
|
||||
setupList(R.id.list1);
|
||||
setupList(R.id.list2);
|
||||
setupList(R.id.list3);
|
||||
|
||||
getWindow().getDecorView().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final View leftList = findViewById(R.id.list1);
|
||||
final View middleList = findViewById(R.id.list2);
|
||||
final View rightList = findViewById(R.id.list3);
|
||||
|
||||
final ObjectAnimator moveRight = ObjectAnimator.ofFloat(leftList,
|
||||
"x", 0, rightList.getLeft());
|
||||
moveRight.setDuration(1500);
|
||||
moveRight.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
moveRight.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
|
||||
final ObjectAnimator moveLeft = ObjectAnimator.ofFloat(rightList,
|
||||
"x", rightList.getLeft(), 0);
|
||||
moveLeft.setDuration(1500);
|
||||
moveLeft.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
moveLeft.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
|
||||
final ObjectAnimator rotate = ObjectAnimator.ofFloat(middleList,
|
||||
"rotationY", 0, 360);
|
||||
rotate.setDuration(3000);
|
||||
rotate.setRepeatCount(ObjectAnimator.INFINITE);
|
||||
rotate.setRepeatMode(ObjectAnimator.REVERSE);
|
||||
|
||||
Paint p = new Paint();
|
||||
p.setColorFilter(new PorterDuffColorFilter(0xffff0000, PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
Paint p2 = new Paint();
|
||||
p2.setAlpha(127);
|
||||
|
||||
Paint p3 = new Paint();
|
||||
p3.setColorFilter(new PorterDuffColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY));
|
||||
|
||||
leftList.setLayerType(View.LAYER_TYPE_SOFTWARE, p);
|
||||
leftList.setAlpha(0.5f);
|
||||
middleList.setLayerType(View.LAYER_TYPE_HARDWARE, p3);
|
||||
middleList.setAlpha(0.5f);
|
||||
rightList.setLayerType(View.LAYER_TYPE_SOFTWARE, p2);
|
||||
|
||||
moveRight.start();
|
||||
moveLeft.start();
|
||||
rotate.start();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
private void setupList(int listId) {
|
||||
final ListView list = (ListView) findViewById(listId);
|
||||
list.setAdapter(new SimpleListAdapter(this));
|
||||
}
|
||||
|
||||
private static class SimpleListAdapter extends ArrayAdapter<String> {
|
||||
public SimpleListAdapter(Context context) {
|
||||
super(context, android.R.layout.simple_list_item_1, DATA_LIST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextView v = (TextView) super.getView(position, convertView, parent);
|
||||
final Resources r = getContext().getResources();
|
||||
final DisplayMetrics metrics = r.getDisplayMetrics();
|
||||
v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f));
|
||||
v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon),
|
||||
null, null, null);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String[] DATA_LIST = {
|
||||
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
|
||||
"Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
|
||||
"Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
|
||||
"Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
|
||||
"Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
|
||||
"Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
|
||||
"British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
|
||||
"Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
|
||||
"Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
|
||||
"Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
|
||||
"Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
|
||||
"Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
|
||||
"East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
|
||||
"Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
|
||||
"Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
|
||||
"French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
|
||||
"Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
|
||||
"Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
|
||||
"Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
|
||||
"Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
|
||||
"Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
|
||||
"Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
|
||||
"Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
|
||||
"Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
|
||||
"Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
|
||||
"Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
|
||||
"Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
|
||||
"Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
|
||||
"Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
|
||||
"Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
|
||||
"Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
|
||||
"Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
|
||||
"Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
|
||||
"Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
|
||||
"Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
|
||||
"The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
|
||||
"Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
|
||||
"Ukraine", "United Arab Emirates", "United Kingdom",
|
||||
"United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
|
||||
"Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
|
||||
"Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user