blob: 130628442dfb9da2f2f137a08f48157a542ce922 [file] [log] [blame]
Dianne Hackborn4c62fc02009-08-08 20:40:27 -07001/*
2 * Copyright (C) 2009 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
Dianne Hackbornba398392011-08-01 16:11:57 -070017package com.android.systemui;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070018
John Spurlockde84f0e2013-06-12 12:41:00 -040019import static android.opengl.GLES20.*;
Winsonc0d70582016-01-29 10:24:39 -080020
John Spurlockde84f0e2013-06-12 12:41:00 -040021import static javax.microedition.khronos.egl.EGL10.*;
22
Romain Guy407ec782011-08-24 17:06:58 -070023import android.app.ActivityManager;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070024import android.app.WallpaperManager;
Chet Haasec61d70e2012-10-10 15:41:57 -070025import android.content.ComponentCallbacks2;
Romain Guy407ec782011-08-24 17:06:58 -070026import android.graphics.Bitmap;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070027import android.graphics.Canvas;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070028import android.graphics.Rect;
Michael Jurka824a4b52013-12-18 17:10:16 +010029import android.graphics.RectF;
Mathias Agopiane2d034c2009-09-23 21:06:17 -070030import android.graphics.Region.Op;
Romain Guy407ec782011-08-24 17:06:58 -070031import android.opengl.GLUtils;
Romain Guy043a6b12011-09-27 15:37:54 -070032import android.os.SystemProperties;
Romain Guy407ec782011-08-24 17:06:58 -070033import android.renderscript.Matrix4f;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070034import android.service.wallpaper.WallpaperService;
Dianne Hackbornc9dbbe22009-11-11 22:50:37 -080035import android.util.Log;
Michael Jurka824a4b52013-12-18 17:10:16 +010036import android.view.Display;
Adrian Roos9b9947d2015-06-09 16:46:05 -070037import android.view.DisplayInfo;
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -070038import android.view.MotionEvent;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070039import android.view.SurfaceHolder;
Chet Haase2f200812012-10-11 12:49:08 -070040import android.view.WindowManager;
Romain Guy407ec782011-08-24 17:06:58 -070041
Adrian Roosab6edbf2015-07-07 17:29:15 -070042import java.io.FileDescriptor;
Romain Guy407ec782011-08-24 17:06:58 -070043import java.io.IOException;
Adrian Roosab6edbf2015-07-07 17:29:15 -070044import java.io.PrintWriter;
Romain Guy407ec782011-08-24 17:06:58 -070045import java.nio.ByteBuffer;
46import java.nio.ByteOrder;
47import java.nio.FloatBuffer;
48
John Spurlockde84f0e2013-06-12 12:41:00 -040049import javax.microedition.khronos.egl.EGL10;
50import javax.microedition.khronos.egl.EGLConfig;
51import javax.microedition.khronos.egl.EGLContext;
52import javax.microedition.khronos.egl.EGLDisplay;
53import javax.microedition.khronos.egl.EGLSurface;
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070054
55/**
56 * Default built-in wallpaper that simply shows a static image.
57 */
Romain Guy407ec782011-08-24 17:06:58 -070058@SuppressWarnings({"UnusedDeclaration"})
Dianne Hackborn4c62fc02009-08-08 20:40:27 -070059public class ImageWallpaper extends WallpaperService {
Jeff Brownfa2e5042011-01-23 13:14:23 -080060 private static final String TAG = "ImageWallpaper";
Romain Guy407ec782011-08-24 17:06:58 -070061 private static final String GL_LOG_TAG = "ImageWallpaperGL";
Jeff Brownfa2e5042011-01-23 13:14:23 -080062 private static final boolean DEBUG = false;
Romain Guy043a6b12011-09-27 15:37:54 -070063 private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu";
Jeff Brownfa2e5042011-01-23 13:14:23 -080064
Dianne Hackbornba398392011-08-01 16:11:57 -070065 static final boolean FIXED_SIZED_SURFACE = true;
Erik Gilling881fb202011-08-25 10:27:52 -070066 static final boolean USE_OPENGL = true;
Dianne Hackbornba398392011-08-01 16:11:57 -070067
Romain Guyef654bd2009-08-11 19:12:17 -070068 WallpaperManager mWallpaperManager;
Romain Guy407ec782011-08-24 17:06:58 -070069
Chet Haasec61d70e2012-10-10 15:41:57 -070070 DrawableEngine mEngine;
71
Romain Guy407ec782011-08-24 17:06:58 -070072 boolean mIsHwAccelerated;
Dianne Hackborn759a39e2009-08-09 17:20:27 -070073
Romain Guyef654bd2009-08-11 19:12:17 -070074 @Override
75 public void onCreate() {
76 super.onCreate();
77 mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
Romain Guy407ec782011-08-24 17:06:58 -070078
79 //noinspection PointlessBooleanExpression,ConstantConditions
80 if (FIXED_SIZED_SURFACE && USE_OPENGL) {
Romain Guy043a6b12011-09-27 15:37:54 -070081 if (!isEmulator()) {
Jeff Brown98365d72012-08-19 20:30:52 -070082 mIsHwAccelerated = ActivityManager.isHighEndGfx();
Romain Guy043a6b12011-09-27 15:37:54 -070083 }
Romain Guy407ec782011-08-24 17:06:58 -070084 }
Romain Guyef654bd2009-08-11 19:12:17 -070085 }
86
Chet Haasec61d70e2012-10-10 15:41:57 -070087 @Override
88 public void onTrimMemory(int level) {
89 if (mEngine != null) {
90 mEngine.trimMemory(level);
91 }
92 }
93
Romain Guy043a6b12011-09-27 15:37:54 -070094 private static boolean isEmulator() {
95 return "1".equals(SystemProperties.get(PROPERTY_KERNEL_QEMU, "0"));
96 }
97
Craig Mautnerb1ef3692012-11-16 17:31:04 -080098 @Override
Romain Guyef654bd2009-08-11 19:12:17 -070099 public Engine onCreateEngine() {
Chet Haasec61d70e2012-10-10 15:41:57 -0700100 mEngine = new DrawableEngine();
101 return mEngine;
Romain Guyef654bd2009-08-11 19:12:17 -0700102 }
103
104 class DrawableEngine extends Engine {
Romain Guy407ec782011-08-24 17:06:58 -0700105 static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
106 static final int EGL_OPENGL_ES2_BIT = 4;
107
Romain Guy407ec782011-08-24 17:06:58 -0700108 Bitmap mBackground;
Michael Jurka824a4b52013-12-18 17:10:16 +0100109 int mBackgroundWidth = -1, mBackgroundHeight = -1;
Chet Haase5f0d9762012-10-18 12:01:34 -0700110 int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
Chet Haase2f200812012-10-11 12:49:08 -0700111 int mLastRotation = -1;
Michael Jurka824a4b52013-12-18 17:10:16 +0100112 float mXOffset = 0.5f;
113 float mYOffset = 0.5f;
114 float mScale = 1f;
Romain Guyef654bd2009-08-11 19:12:17 -0700115
Adrian Roos9b9947d2015-06-09 16:46:05 -0700116 private Display mDefaultDisplay;
117 private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
118
Jeff Brownfa2e5042011-01-23 13:14:23 -0800119 boolean mVisible = true;
Jeff Brownfa2e5042011-01-23 13:14:23 -0800120 boolean mOffsetsChanged;
121 int mLastXTranslation;
122 int mLastYTranslation;
123
Romain Guy407ec782011-08-24 17:06:58 -0700124 private EGL10 mEgl;
125 private EGLDisplay mEglDisplay;
126 private EGLConfig mEglConfig;
127 private EGLContext mEglContext;
128 private EGLSurface mEglSurface;
Romain Guy407ec782011-08-24 17:06:58 -0700129
130 private static final String sSimpleVS =
131 "attribute vec4 position;\n" +
132 "attribute vec2 texCoords;\n" +
133 "varying vec2 outTexCoords;\n" +
134 "uniform mat4 projection;\n" +
135 "\nvoid main(void) {\n" +
136 " outTexCoords = texCoords;\n" +
137 " gl_Position = projection * position;\n" +
138 "}\n\n";
139 private static final String sSimpleFS =
140 "precision mediump float;\n\n" +
141 "varying vec2 outTexCoords;\n" +
142 "uniform sampler2D texture;\n" +
143 "\nvoid main(void) {\n" +
144 " gl_FragColor = texture2D(texture, outTexCoords);\n" +
145 "}\n\n";
John Spurlock209bede2013-07-17 12:23:27 -0400146
Romain Guy407ec782011-08-24 17:06:58 -0700147 private static final int FLOAT_SIZE_BYTES = 4;
148 private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES;
149 private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0;
150 private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3;
151
Adrian Roosab6edbf2015-07-07 17:29:15 -0700152 private int mRotationAtLastSurfaceSizeUpdate = -1;
153 private int mDisplayWidthAtLastSurfaceSizeUpdate = -1;
154 private int mDisplayHeightAtLastSurfaceSizeUpdate = -1;
155
Adrian Roos30a7dfa2015-07-17 12:29:53 -0700156 private int mLastRequestedWidth = -1;
157 private int mLastRequestedHeight = -1;
158
Jeff Sharkey35be7562012-04-18 19:16:15 -0700159 public DrawableEngine() {
160 super();
161 setFixedSizeAllowed(true);
162 }
163
Chet Haasec61d70e2012-10-10 15:41:57 -0700164 public void trimMemory(int level) {
165 if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW &&
Adrian Roos2acaeda2014-11-12 18:02:42 +0100166 mBackground != null) {
Chet Haase5f0d9762012-10-18 12:01:34 -0700167 if (DEBUG) {
168 Log.d(TAG, "trimMemory");
169 }
Chet Haasec61d70e2012-10-10 15:41:57 -0700170 mBackground.recycle();
171 mBackground = null;
Michael Jurka824a4b52013-12-18 17:10:16 +0100172 mBackgroundWidth = -1;
173 mBackgroundHeight = -1;
Chet Haasec61d70e2012-10-10 15:41:57 -0700174 mWallpaperManager.forgetLoadedWallpaper();
175 }
176 }
177
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700178 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700179 public void onCreate(SurfaceHolder surfaceHolder) {
Jeff Brown30bc34f2011-01-25 12:56:56 -0800180 if (DEBUG) {
181 Log.d(TAG, "onCreate");
182 }
183
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700184 super.onCreate(surfaceHolder);
John Spurlock209bede2013-07-17 12:23:27 -0400185
Adrian Roos9b9947d2015-06-09 16:46:05 -0700186 mDefaultDisplay = getSystemService(WindowManager.class).getDefaultDisplay();
187
188 updateSurfaceSize(surfaceHolder, getDefaultDisplayInfo());
Chet Haasea8e5a2b2011-10-28 13:18:16 -0700189
190 setOffsetNotificationsEnabled(false);
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700191 }
192
193 @Override
Dianne Hackborn284ac932009-08-28 10:34:25 -0700194 public void onDestroy() {
195 super.onDestroy();
jshe32X7670b2b2013-10-24 12:57:09 +0800196 mBackground = null;
Adrian Roos2acaeda2014-11-12 18:02:42 +0100197 mWallpaperManager.forgetLoadedWallpaper();
Dianne Hackborn284ac932009-08-28 10:34:25 -0700198 }
199
Adrian Roos9b9947d2015-06-09 16:46:05 -0700200 void updateSurfaceSize(SurfaceHolder surfaceHolder, DisplayInfo displayInfo) {
Michael Jurka824a4b52013-12-18 17:10:16 +0100201 // Load background image dimensions, if we haven't saved them yet
202 if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
203 // Need to load the image to get dimensions
204 mWallpaperManager.forgetLoadedWallpaper();
205 updateWallpaperLocked();
206 if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) {
207 // Default to the display size if we can't find the dimensions
Adrian Roos9b9947d2015-06-09 16:46:05 -0700208 mBackgroundWidth = displayInfo.logicalWidth;
209 mBackgroundHeight = displayInfo.logicalHeight;
Michael Jurka824a4b52013-12-18 17:10:16 +0100210 }
211 }
212
213 // Force the wallpaper to cover the screen in both dimensions
Adrian Roos9b9947d2015-06-09 16:46:05 -0700214 int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth);
215 int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight);
Michael Jurka824a4b52013-12-18 17:10:16 +0100216
Dianne Hackbornba398392011-08-01 16:11:57 -0700217 if (FIXED_SIZED_SURFACE) {
218 // Used a fixed size surface, because we are special. We can do
219 // this because we know the current design of window animations doesn't
220 // cause this to break.
Michael Jurka824a4b52013-12-18 17:10:16 +0100221 surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight);
Adrian Roos30a7dfa2015-07-17 12:29:53 -0700222 mLastRequestedWidth = surfaceWidth;
223 mLastRequestedHeight = surfaceHeight;
Dianne Hackbornba398392011-08-01 16:11:57 -0700224 } else {
225 surfaceHolder.setSizeFromLayout();
226 }
Dianne Hackbornac1471a2011-02-03 13:46:06 -0800227 }
228
229 @Override
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700230 public void onVisibilityChanged(boolean visible) {
Jeff Brown30bc34f2011-01-25 12:56:56 -0800231 if (DEBUG) {
Chet Haase2f200812012-10-11 12:49:08 -0700232 Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible);
Jeff Brown30bc34f2011-01-25 12:56:56 -0800233 }
234
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800235 if (mVisible != visible) {
236 if (DEBUG) {
237 Log.d(TAG, "Visibility changed to visible=" + visible);
Jeff Brown30bc34f2011-01-25 12:56:56 -0800238 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800239 mVisible = visible;
longyu.huang6b53fd22015-05-06 01:46:23 -0700240 if (visible) {
241 drawFrame();
242 }
Jeff Brownfa2e5042011-01-23 13:14:23 -0800243 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700244 }
Jeff Brownfa2e5042011-01-23 13:14:23 -0800245
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700246 @Override
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700247 public void onTouchEvent(MotionEvent event) {
248 super.onTouchEvent(event);
Dianne Hackborn8df8b2b2009-08-17 15:15:18 -0700249 }
250
251 @Override
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700252 public void onOffsetsChanged(float xOffset, float yOffset,
Marco Nelissenbf6956b2009-11-09 15:21:13 -0800253 float xOffsetStep, float yOffsetStep,
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700254 int xPixels, int yPixels) {
Jeff Brown30bc34f2011-01-25 12:56:56 -0800255 if (DEBUG) {
256 Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset
257 + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep
258 + ", xPixels=" + xPixels + ", yPixels=" + yPixels);
259 }
260
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800261 if (mXOffset != xOffset || mYOffset != yOffset) {
262 if (DEBUG) {
263 Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ").");
Jeff Brownfa2e5042011-01-23 13:14:23 -0800264 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800265 mXOffset = xOffset;
266 mYOffset = yOffset;
267 mOffsetsChanged = true;
Jeff Brownfa2e5042011-01-23 13:14:23 -0800268 }
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800269 drawFrame();
Dianne Hackborn72c82ab2009-08-11 21:13:54 -0700270 }
271
272 @Override
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700273 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Jeff Brown30bc34f2011-01-25 12:56:56 -0800274 if (DEBUG) {
275 Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height);
276 }
277
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700278 super.onSurfaceChanged(holder, format, width, height);
Jeff Brown30bc34f2011-01-25 12:56:56 -0800279
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800280 drawFrame();
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700281 }
282
Craig Mautnerfb729c72012-10-01 09:39:43 -0700283 @Override
Chet Haase2f200812012-10-11 12:49:08 -0700284 public void onSurfaceDestroyed(SurfaceHolder holder) {
285 super.onSurfaceDestroyed(holder);
Chet Haase5f0d9762012-10-18 12:01:34 -0700286 mLastSurfaceWidth = mLastSurfaceHeight = -1;
Chet Haase2f200812012-10-11 12:49:08 -0700287 }
288
289 @Override
290 public void onSurfaceCreated(SurfaceHolder holder) {
291 super.onSurfaceCreated(holder);
Chet Haase5f0d9762012-10-18 12:01:34 -0700292 mLastSurfaceWidth = mLastSurfaceHeight = -1;
Chet Haase2f200812012-10-11 12:49:08 -0700293 }
294
295 @Override
Craig Mautnerfb729c72012-10-01 09:39:43 -0700296 public void onSurfaceRedrawNeeded(SurfaceHolder holder) {
297 if (DEBUG) {
Chet Haase2f200812012-10-11 12:49:08 -0700298 Log.d(TAG, "onSurfaceRedrawNeeded");
Craig Mautnerfb729c72012-10-01 09:39:43 -0700299 }
300 super.onSurfaceRedrawNeeded(holder);
301
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800302 drawFrame();
Craig Mautnerfb729c72012-10-01 09:39:43 -0700303 }
304
Adrian Roos9b9947d2015-06-09 16:46:05 -0700305 private DisplayInfo getDefaultDisplayInfo() {
306 mDefaultDisplay.getDisplayInfo(mTmpDisplayInfo);
307 return mTmpDisplayInfo;
Michael Jurka824a4b52013-12-18 17:10:16 +0100308 }
309
Craig Mautnerb1ef3692012-11-16 17:31:04 -0800310 void drawFrame() {
Adrian Roos2acaeda2014-11-12 18:02:42 +0100311 try {
Adrian Roos9b9947d2015-06-09 16:46:05 -0700312 DisplayInfo displayInfo = getDefaultDisplayInfo();
313 int newRotation = displayInfo.rotation;
Michael Jurka824a4b52013-12-18 17:10:16 +0100314
Adrian Roos2acaeda2014-11-12 18:02:42 +0100315 // Sometimes a wallpaper is not large enough to cover the screen in one dimension.
316 // Call updateSurfaceSize -- it will only actually do the update if the dimensions
317 // should change
318 if (newRotation != mLastRotation) {
319 // Update surface size (if necessary)
Adrian Roos9b9947d2015-06-09 16:46:05 -0700320 updateSurfaceSize(getSurfaceHolder(), displayInfo);
Adrian Roosab6edbf2015-07-07 17:29:15 -0700321 mRotationAtLastSurfaceSizeUpdate = newRotation;
322 mDisplayWidthAtLastSurfaceSizeUpdate = displayInfo.logicalWidth;
323 mDisplayHeightAtLastSurfaceSizeUpdate = displayInfo.logicalHeight;
Chet Haase2f200812012-10-11 12:49:08 -0700324 }
Adrian Roos2acaeda2014-11-12 18:02:42 +0100325 SurfaceHolder sh = getSurfaceHolder();
326 final Rect frame = sh.getSurfaceFrame();
327 final int dw = frame.width();
328 final int dh = frame.height();
329 boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth
330 || dh != mLastSurfaceHeight;
Chet Haase2f200812012-10-11 12:49:08 -0700331
Adrian Roos2acaeda2014-11-12 18:02:42 +0100332 boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation;
333 if (!redrawNeeded && !mOffsetsChanged) {
Chet Haase5f0d9762012-10-18 12:01:34 -0700334 if (DEBUG) {
Adrian Roos2acaeda2014-11-12 18:02:42 +0100335 Log.d(TAG, "Suppressed drawFrame since redraw is not needed "
336 + "and offsets have not changed.");
Chet Haase5f0d9762012-10-18 12:01:34 -0700337 }
338 return;
339 }
Adrian Roos2acaeda2014-11-12 18:02:42 +0100340 mLastRotation = newRotation;
341
342 // Load bitmap if it is not yet loaded or if it was loaded at a different size
343 if (mBackground == null || surfaceDimensionsChanged) {
344 if (DEBUG) {
345 Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " +
346 mBackground + ", " +
347 ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " +
348 ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " +
349 dw + ", " + dh);
350 }
351 mWallpaperManager.forgetLoadedWallpaper();
352 updateWallpaperLocked();
353 if (mBackground == null) {
354 if (DEBUG) {
355 Log.d(TAG, "Unable to load bitmap");
356 }
357 return;
358 }
359 if (DEBUG) {
360 if (dw != mBackground.getWidth() || dh != mBackground.getHeight()) {
361 Log.d(TAG, "Surface != bitmap dimensions: surface w/h, bitmap w/h: " +
362 dw + ", " + dh + ", " + mBackground.getWidth() + ", " +
363 mBackground.getHeight());
364 }
Chet Haase5f0d9762012-10-18 12:01:34 -0700365 }
366 }
Chet Haase2f200812012-10-11 12:49:08 -0700367
Adrian Roos2acaeda2014-11-12 18:02:42 +0100368 // Center the scaled image
369 mScale = Math.max(1f, Math.max(dw / (float) mBackground.getWidth(),
370 dh / (float) mBackground.getHeight()));
371 final int availw = dw - (int) (mBackground.getWidth() * mScale);
372 final int availh = dh - (int) (mBackground.getHeight() * mScale);
373 int xPixels = availw / 2;
374 int yPixels = availh / 2;
Michael Jurka824a4b52013-12-18 17:10:16 +0100375
Adrian Roos2acaeda2014-11-12 18:02:42 +0100376 // Adjust the image for xOffset/yOffset values. If window manager is handling offsets,
377 // mXOffset and mYOffset are set to 0.5f by default and therefore xPixels and yPixels
378 // will remain unchanged
379 final int availwUnscaled = dw - mBackground.getWidth();
380 final int availhUnscaled = dh - mBackground.getHeight();
381 if (availwUnscaled < 0)
382 xPixels += (int) (availwUnscaled * (mXOffset - .5f) + .5f);
383 if (availhUnscaled < 0)
384 yPixels += (int) (availhUnscaled * (mYOffset - .5f) + .5f);
Jeff Brown033f63a2011-01-23 22:01:49 -0800385
Adrian Roos2acaeda2014-11-12 18:02:42 +0100386 mOffsetsChanged = false;
Adrian Roos2acaeda2014-11-12 18:02:42 +0100387 if (surfaceDimensionsChanged) {
388 mLastSurfaceWidth = dw;
389 mLastSurfaceHeight = dh;
Jeff Brown033f63a2011-01-23 22:01:49 -0800390 }
Adrian Roos2acaeda2014-11-12 18:02:42 +0100391 if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) {
392 if (DEBUG) {
393 Log.d(TAG, "Suppressed drawFrame since the image has not "
394 + "actually moved an integral number of pixels.");
395 }
396 return;
397 }
398 mLastXTranslation = xPixels;
399 mLastYTranslation = yPixels;
Jeff Brown033f63a2011-01-23 22:01:49 -0800400
Adrian Roos2acaeda2014-11-12 18:02:42 +0100401 if (DEBUG) {
402 Log.d(TAG, "Redrawing wallpaper");
403 }
Wim Vander Schelden9549c062013-02-07 15:51:51 +0000404
Adrian Roos2acaeda2014-11-12 18:02:42 +0100405 if (mIsHwAccelerated) {
406 if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) {
407 drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
408 }
409 } else {
Romain Guyf9296292011-08-25 17:00:39 -0700410 drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
411 }
Adrian Roos2acaeda2014-11-12 18:02:42 +0100412 } finally {
413 if (FIXED_SIZED_SURFACE && !mIsHwAccelerated) {
Chet Haasec61d70e2012-10-10 15:41:57 -0700414 // If the surface is fixed-size, we should only need to
415 // draw it once and then we'll let the window manager
416 // position it appropriately. As such, we no longer needed
417 // the loaded bitmap. Yay!
Adrian Roos2acaeda2014-11-12 18:02:42 +0100418 // hw-accelerated renderer retains bitmap for faster rotation
Chet Haasec61d70e2012-10-10 15:41:57 -0700419 mBackground = null;
420 mWallpaperManager.forgetLoadedWallpaper();
421 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700422 }
Dianne Hackborn759a39e2009-08-09 17:20:27 -0700423 }
Romain Guyef654bd2009-08-11 19:12:17 -0700424
Chet Haase5f0d9762012-10-18 12:01:34 -0700425 private void updateWallpaperLocked() {
Jeff Brownfa2e5042011-01-23 13:14:23 -0800426 Throwable exception = null;
427 try {
Chet Haase589a6af2012-10-24 17:37:00 -0700428 mBackground = null;
Michael Jurka824a4b52013-12-18 17:10:16 +0100429 mBackgroundWidth = -1;
430 mBackgroundHeight = -1;
Romain Guy407ec782011-08-24 17:06:58 -0700431 mBackground = mWallpaperManager.getBitmap();
Michael Jurka824a4b52013-12-18 17:10:16 +0100432 mBackgroundWidth = mBackground.getWidth();
433 mBackgroundHeight = mBackground.getHeight();
Jeff Brownfa2e5042011-01-23 13:14:23 -0800434 } catch (RuntimeException e) {
435 exception = e;
436 } catch (OutOfMemoryError e) {
437 exception = e;
438 }
Romain Guy407ec782011-08-24 17:06:58 -0700439
Jeff Brownfa2e5042011-01-23 13:14:23 -0800440 if (exception != null) {
441 mBackground = null;
Michael Jurka824a4b52013-12-18 17:10:16 +0100442 mBackgroundWidth = -1;
443 mBackgroundHeight = -1;
Jeff Brownfa2e5042011-01-23 13:14:23 -0800444 // Note that if we do fail at this, and the default wallpaper can't
445 // be loaded, we will go into a cycle. Don't do a build where the
446 // default wallpaper can't be loaded.
447 Log.w(TAG, "Unable to load wallpaper!", exception);
Dianne Hackbornc9dbbe22009-11-11 22:50:37 -0800448 try {
Jeff Brownfa2e5042011-01-23 13:14:23 -0800449 mWallpaperManager.clear();
450 } catch (IOException ex) {
451 // now we're really screwed.
452 Log.w(TAG, "Unable reset to default wallpaper!", ex);
Dianne Hackbornc9dbbe22009-11-11 22:50:37 -0800453 }
Romain Guyef654bd2009-08-11 19:12:17 -0700454 }
Romain Guy407ec782011-08-24 17:06:58 -0700455 }
456
Adrian Roosab6edbf2015-07-07 17:29:15 -0700457 @Override
458 protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
459 super.dump(prefix, fd, out, args);
460
461 out.print(prefix); out.println("ImageWallpaper.DrawableEngine:");
462 out.print(prefix); out.print(" mBackground="); out.print(mBackground);
463 out.print(" mBackgroundWidth="); out.print(mBackgroundWidth);
464 out.print(" mBackgroundHeight="); out.println(mBackgroundHeight);
465
466 out.print(prefix); out.print(" mLastRotation="); out.print(mLastRotation);
467 out.print(" mLastSurfaceWidth="); out.print(mLastSurfaceWidth);
468 out.print(" mLastSurfaceHeight="); out.println(mLastSurfaceHeight);
469
470 out.print(prefix); out.print(" mXOffset="); out.print(mXOffset);
471 out.print(" mYOffset="); out.println(mYOffset);
472
473 out.print(prefix); out.print(" mVisible="); out.print(mVisible);
Adrian Roosab6edbf2015-07-07 17:29:15 -0700474 out.print(" mOffsetsChanged="); out.println(mOffsetsChanged);
475
476 out.print(prefix); out.print(" mLastXTranslation="); out.print(mLastXTranslation);
477 out.print(" mLastYTranslation="); out.print(mLastYTranslation);
478 out.print(" mScale="); out.println(mScale);
479
Adrian Roos30a7dfa2015-07-17 12:29:53 -0700480 out.print(prefix); out.print(" mLastRequestedWidth="); out.print(mLastRequestedWidth);
481 out.print(" mLastRequestedHeight="); out.println(mLastRequestedHeight);
482
Adrian Roosab6edbf2015-07-07 17:29:15 -0700483 out.print(prefix); out.println(" DisplayInfo at last updateSurfaceSize:");
484 out.print(prefix);
485 out.print(" rotation="); out.print(mRotationAtLastSurfaceSizeUpdate);
486 out.print(" width="); out.print(mDisplayWidthAtLastSurfaceSizeUpdate);
487 out.print(" height="); out.println(mDisplayHeightAtLastSurfaceSizeUpdate);
488 }
489
Michael Jurka824a4b52013-12-18 17:10:16 +0100490 private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) {
Romain Guy407ec782011-08-24 17:06:58 -0700491 Canvas c = sh.lockCanvas();
492 if (c != null) {
493 try {
494 if (DEBUG) {
Michael Jurka824a4b52013-12-18 17:10:16 +0100495 Log.d(TAG, "Redrawing: left=" + left + ", top=" + top);
Romain Guy407ec782011-08-24 17:06:58 -0700496 }
497
Michael Jurka824a4b52013-12-18 17:10:16 +0100498 final float right = left + mBackground.getWidth() * mScale;
499 final float bottom = top + mBackground.getHeight() * mScale;
Romain Guy407ec782011-08-24 17:06:58 -0700500 if (w < 0 || h < 0) {
501 c.save(Canvas.CLIP_SAVE_FLAG);
Michael Jurka824a4b52013-12-18 17:10:16 +0100502 c.clipRect(left, top, right, bottom,
Chet Haase5f0d9762012-10-18 12:01:34 -0700503 Op.DIFFERENCE);
Romain Guy407ec782011-08-24 17:06:58 -0700504 c.drawColor(0xff000000);
505 c.restore();
506 }
507 if (mBackground != null) {
Michael Jurka824a4b52013-12-18 17:10:16 +0100508 RectF dest = new RectF(left, top, right, bottom);
509 // add a filter bitmap?
510 c.drawBitmap(mBackground, null, dest, null);
Romain Guy407ec782011-08-24 17:06:58 -0700511 }
512 } finally {
513 sh.unlockCanvasAndPost(c);
514 }
515 }
516 }
517
Romain Guyf9296292011-08-25 17:00:39 -0700518 private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) {
519 if (!initGL(sh)) return false;
Romain Guy407ec782011-08-24 17:06:58 -0700520
Michael Jurka824a4b52013-12-18 17:10:16 +0100521 final float right = left + mBackground.getWidth() * mScale;
522 final float bottom = top + mBackground.getHeight() * mScale;
Romain Guy407ec782011-08-24 17:06:58 -0700523
524 final Rect frame = sh.getSurfaceFrame();
Romain Guy407ec782011-08-24 17:06:58 -0700525 final Matrix4f ortho = new Matrix4f();
526 ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f);
527
528 final FloatBuffer triangleVertices = createMesh(left, top, right, bottom);
529
530 final int texture = loadTexture(mBackground);
531 final int program = buildProgram(sSimpleVS, sSimpleFS);
Chet Haase2f200812012-10-11 12:49:08 -0700532
Romain Guy407ec782011-08-24 17:06:58 -0700533 final int attribPosition = glGetAttribLocation(program, "position");
534 final int attribTexCoords = glGetAttribLocation(program, "texCoords");
535 final int uniformTexture = glGetUniformLocation(program, "texture");
536 final int uniformProjection = glGetUniformLocation(program, "projection");
537
538 checkGlError();
539
540 glViewport(0, 0, frame.width(), frame.height());
541 glBindTexture(GL_TEXTURE_2D, texture);
542
543 glUseProgram(program);
544 glEnableVertexAttribArray(attribPosition);
545 glEnableVertexAttribArray(attribTexCoords);
546 glUniform1i(uniformTexture, 0);
547 glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0);
548
549 checkGlError();
550
Michael Wright6762a442013-10-15 14:43:32 -0700551 if (w > 0 || h > 0) {
Romain Guy407ec782011-08-24 17:06:58 -0700552 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
553 glClear(GL_COLOR_BUFFER_BIT);
554 }
Chet Haase2f200812012-10-11 12:49:08 -0700555
Romain Guy407ec782011-08-24 17:06:58 -0700556 // drawQuad
557 triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
558 glVertexAttribPointer(attribPosition, 3, GL_FLOAT, false,
559 TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
560
561 triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
562 glVertexAttribPointer(attribTexCoords, 3, GL_FLOAT, false,
563 TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices);
564
565 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Chet Haase2f200812012-10-11 12:49:08 -0700566
Romain Guyc8d983f2013-02-20 10:05:36 -0800567 boolean status = mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
Romain Guy407ec782011-08-24 17:06:58 -0700568 checkEglError();
Chet Haase2f200812012-10-11 12:49:08 -0700569
Michael Wright2ed05132015-01-08 14:30:47 -0800570 finishGL(texture, program);
Romain Guyf9296292011-08-25 17:00:39 -0700571
Romain Guyc8d983f2013-02-20 10:05:36 -0800572 return status;
Romain Guy407ec782011-08-24 17:06:58 -0700573 }
574
575 private FloatBuffer createMesh(int left, int top, float right, float bottom) {
576 final float[] verticesData = {
577 // X, Y, Z, U, V
578 left, bottom, 0.0f, 0.0f, 1.0f,
579 right, bottom, 0.0f, 1.0f, 1.0f,
580 left, top, 0.0f, 0.0f, 0.0f,
581 right, top, 0.0f, 1.0f, 0.0f,
582 };
583
584 final int bytes = verticesData.length * FLOAT_SIZE_BYTES;
585 final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order(
586 ByteOrder.nativeOrder()).asFloatBuffer();
587 triangleVertices.put(verticesData).position(0);
588 return triangleVertices;
589 }
590
591 private int loadTexture(Bitmap bitmap) {
592 int[] textures = new int[1];
John Spurlock209bede2013-07-17 12:23:27 -0400593
Romain Guy407ec782011-08-24 17:06:58 -0700594 glActiveTexture(GL_TEXTURE0);
595 glGenTextures(1, textures, 0);
596 checkGlError();
John Spurlock209bede2013-07-17 12:23:27 -0400597
Romain Guy407ec782011-08-24 17:06:58 -0700598 int texture = textures[0];
599 glBindTexture(GL_TEXTURE_2D, texture);
600 checkGlError();
John Spurlock209bede2013-07-17 12:23:27 -0400601
Romain Guy407ec782011-08-24 17:06:58 -0700602 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
John Spurlock209bede2013-07-17 12:23:27 -0400604
Romain Guy407ec782011-08-24 17:06:58 -0700605 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
606 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
John Spurlock209bede2013-07-17 12:23:27 -0400607
Romain Guy407ec782011-08-24 17:06:58 -0700608 GLUtils.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap, GL_UNSIGNED_BYTE, 0);
609 checkGlError();
610
Romain Guy407ec782011-08-24 17:06:58 -0700611 return texture;
612 }
John Spurlock209bede2013-07-17 12:23:27 -0400613
Romain Guy407ec782011-08-24 17:06:58 -0700614 private int buildProgram(String vertex, String fragment) {
615 int vertexShader = buildShader(vertex, GL_VERTEX_SHADER);
616 if (vertexShader == 0) return 0;
John Spurlock209bede2013-07-17 12:23:27 -0400617
Romain Guy407ec782011-08-24 17:06:58 -0700618 int fragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
619 if (fragmentShader == 0) return 0;
John Spurlock209bede2013-07-17 12:23:27 -0400620
Romain Guy407ec782011-08-24 17:06:58 -0700621 int program = glCreateProgram();
622 glAttachShader(program, vertexShader);
Romain Guy407ec782011-08-24 17:06:58 -0700623 glAttachShader(program, fragmentShader);
Romain Guy407ec782011-08-24 17:06:58 -0700624 glLinkProgram(program);
625 checkGlError();
John Spurlock209bede2013-07-17 12:23:27 -0400626
Michael Wright2ed05132015-01-08 14:30:47 -0800627 glDeleteShader(vertexShader);
628 glDeleteShader(fragmentShader);
629
Romain Guy407ec782011-08-24 17:06:58 -0700630 int[] status = new int[1];
631 glGetProgramiv(program, GL_LINK_STATUS, status, 0);
632 if (status[0] != GL_TRUE) {
633 String error = glGetProgramInfoLog(program);
634 Log.d(GL_LOG_TAG, "Error while linking program:\n" + error);
Romain Guy407ec782011-08-24 17:06:58 -0700635 glDeleteProgram(program);
636 return 0;
637 }
John Spurlock209bede2013-07-17 12:23:27 -0400638
Romain Guy407ec782011-08-24 17:06:58 -0700639 return program;
640 }
Romain Guy3696779b2013-01-28 14:04:07 -0800641
Romain Guy407ec782011-08-24 17:06:58 -0700642 private int buildShader(String source, int type) {
643 int shader = glCreateShader(type);
John Spurlock209bede2013-07-17 12:23:27 -0400644
Romain Guy407ec782011-08-24 17:06:58 -0700645 glShaderSource(shader, source);
646 checkGlError();
John Spurlock209bede2013-07-17 12:23:27 -0400647
Romain Guy407ec782011-08-24 17:06:58 -0700648 glCompileShader(shader);
649 checkGlError();
John Spurlock209bede2013-07-17 12:23:27 -0400650
Romain Guy407ec782011-08-24 17:06:58 -0700651 int[] status = new int[1];
652 glGetShaderiv(shader, GL_COMPILE_STATUS, status, 0);
653 if (status[0] != GL_TRUE) {
654 String error = glGetShaderInfoLog(shader);
655 Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error);
656 glDeleteShader(shader);
657 return 0;
658 }
John Spurlock209bede2013-07-17 12:23:27 -0400659
Romain Guy407ec782011-08-24 17:06:58 -0700660 return shader;
661 }
Romain Guy3696779b2013-01-28 14:04:07 -0800662
Romain Guy407ec782011-08-24 17:06:58 -0700663 private void checkEglError() {
664 int error = mEgl.eglGetError();
665 if (error != EGL_SUCCESS) {
666 Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error));
667 }
668 }
Romain Guy3696779b2013-01-28 14:04:07 -0800669
Romain Guy407ec782011-08-24 17:06:58 -0700670 private void checkGlError() {
671 int error = glGetError();
672 if (error != GL_NO_ERROR) {
673 Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable());
674 }
675 }
Romain Guy3696779b2013-01-28 14:04:07 -0800676
Michael Wright2ed05132015-01-08 14:30:47 -0800677 private void finishGL(int texture, int program) {
678 int[] textures = new int[1];
679 textures[0] = texture;
680 glDeleteTextures(1, textures, 0);
681 glDeleteProgram(program);
Romain Guyf9296292011-08-25 17:00:39 -0700682 mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
Romain Guy407ec782011-08-24 17:06:58 -0700683 mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
Romain Guyf9296292011-08-25 17:00:39 -0700684 mEgl.eglDestroyContext(mEglDisplay, mEglContext);
Romain Guy3696779b2013-01-28 14:04:07 -0800685 mEgl.eglTerminate(mEglDisplay);
Romain Guy407ec782011-08-24 17:06:58 -0700686 }
Romain Guy3696779b2013-01-28 14:04:07 -0800687
Romain Guyf9296292011-08-25 17:00:39 -0700688 private boolean initGL(SurfaceHolder surfaceHolder) {
Romain Guy407ec782011-08-24 17:06:58 -0700689 mEgl = (EGL10) EGLContext.getEGL();
John Spurlock209bede2013-07-17 12:23:27 -0400690
Romain Guy407ec782011-08-24 17:06:58 -0700691 mEglDisplay = mEgl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
692 if (mEglDisplay == EGL_NO_DISPLAY) {
693 throw new RuntimeException("eglGetDisplay failed " +
694 GLUtils.getEGLErrorString(mEgl.eglGetError()));
695 }
John Spurlock209bede2013-07-17 12:23:27 -0400696
Romain Guy407ec782011-08-24 17:06:58 -0700697 int[] version = new int[2];
698 if (!mEgl.eglInitialize(mEglDisplay, version)) {
699 throw new RuntimeException("eglInitialize failed " +
700 GLUtils.getEGLErrorString(mEgl.eglGetError()));
701 }
John Spurlock209bede2013-07-17 12:23:27 -0400702
Romain Guy407ec782011-08-24 17:06:58 -0700703 mEglConfig = chooseEglConfig();
704 if (mEglConfig == null) {
705 throw new RuntimeException("eglConfig not initialized");
706 }
John Spurlock209bede2013-07-17 12:23:27 -0400707
Romain Guy407ec782011-08-24 17:06:58 -0700708 mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);
Chet Haase187e1e22013-03-13 18:04:00 -0700709 if (mEglContext == EGL_NO_CONTEXT) {
710 throw new RuntimeException("createContext failed " +
711 GLUtils.getEGLErrorString(mEgl.eglGetError()));
Wim Vander Schelden9549c062013-02-07 15:51:51 +0000712 }
Chet Haase187e1e22013-03-13 18:04:00 -0700713
Chet Haase2e417be2013-03-14 09:28:42 -0700714 int attribs[] = {
715 EGL_WIDTH, 1,
716 EGL_HEIGHT, 1,
717 EGL_NONE
718 };
719 EGLSurface tmpSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
720 mEgl.eglMakeCurrent(mEglDisplay, tmpSurface, tmpSurface, mEglContext);
721
722 int[] maxSize = new int[1];
723 Rect frame = surfaceHolder.getSurfaceFrame();
724 glGetIntegerv(GL_MAX_TEXTURE_SIZE, maxSize, 0);
725
726 mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
727 mEgl.eglDestroySurface(mEglDisplay, tmpSurface);
728
729 if(frame.width() > maxSize[0] || frame.height() > maxSize[0]) {
730 mEgl.eglDestroyContext(mEglDisplay, mEglContext);
731 mEgl.eglTerminate(mEglDisplay);
732 Log.e(GL_LOG_TAG, "requested texture size " +
733 frame.width() + "x" + frame.height() + " exceeds the support maximum of " +
734 maxSize[0] + "x" + maxSize[0]);
735 return false;
736 }
737
Romain Guy407ec782011-08-24 17:06:58 -0700738 mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null);
Romain Guy407ec782011-08-24 17:06:58 -0700739 if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) {
740 int error = mEgl.eglGetError();
Wim Vander Schelden9549c062013-02-07 15:51:51 +0000741 if (error == EGL_BAD_NATIVE_WINDOW || error == EGL_BAD_ALLOC) {
742 Log.e(GL_LOG_TAG, "createWindowSurface returned " +
743 GLUtils.getEGLErrorString(error) + ".");
Romain Guyf9296292011-08-25 17:00:39 -0700744 return false;
Romain Guy407ec782011-08-24 17:06:58 -0700745 }
746 throw new RuntimeException("createWindowSurface failed " +
747 GLUtils.getEGLErrorString(error));
748 }
John Spurlock209bede2013-07-17 12:23:27 -0400749
Romain Guy407ec782011-08-24 17:06:58 -0700750 if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
751 throw new RuntimeException("eglMakeCurrent failed " +
752 GLUtils.getEGLErrorString(mEgl.eglGetError()));
753 }
Romain Guyf9296292011-08-25 17:00:39 -0700754
755 return true;
Romain Guy407ec782011-08-24 17:06:58 -0700756 }
John Spurlock209bede2013-07-17 12:23:27 -0400757
758
Romain Guy407ec782011-08-24 17:06:58 -0700759 EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
760 int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
John Spurlock209bede2013-07-17 12:23:27 -0400761 return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attrib_list);
Romain Guy407ec782011-08-24 17:06:58 -0700762 }
John Spurlock209bede2013-07-17 12:23:27 -0400763
Romain Guy407ec782011-08-24 17:06:58 -0700764 private EGLConfig chooseEglConfig() {
765 int[] configsCount = new int[1];
766 EGLConfig[] configs = new EGLConfig[1];
767 int[] configSpec = getConfig();
768 if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
769 throw new IllegalArgumentException("eglChooseConfig failed " +
770 GLUtils.getEGLErrorString(mEgl.eglGetError()));
771 } else if (configsCount[0] > 0) {
772 return configs[0];
773 }
774 return null;
775 }
776
777 private int[] getConfig() {
778 return new int[] {
779 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
780 EGL_RED_SIZE, 8,
781 EGL_GREEN_SIZE, 8,
782 EGL_BLUE_SIZE, 8,
783 EGL_ALPHA_SIZE, 0,
784 EGL_DEPTH_SIZE, 0,
785 EGL_STENCIL_SIZE, 0,
Romain Guy8efca542012-10-15 18:09:49 -0700786 EGL_CONFIG_CAVEAT, EGL_NONE,
Romain Guy407ec782011-08-24 17:06:58 -0700787 EGL_NONE
788 };
Romain Guyef654bd2009-08-11 19:12:17 -0700789 }
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700790 }
791}