- /*
- * Copyright (C) 2008 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.
- */
- import java.io.Writer;
- import java.util.ArrayList;
-
- import javax.microedition.khronos.egl.EGL10;
- import javax.microedition.khronos.egl.EGL11;
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.egl.EGLContext;
- import javax.microedition.khronos.egl.EGLDisplay;
- import javax.microedition.khronos.egl.EGLSurface;
- import javax.microedition.khronos.opengles.GL;
- import javax.microedition.khronos.opengles.GL10;
-
- import android.service.wallpaper.WallpaperService;
- import android.util.Log;
- import android.view.SurfaceHolder;
-
- import com.mediawoz.firewallpaper.BaseConfigChooser.ComponentSizeChooser;
- import com.mediawoz.firewallpaper.BaseConfigChooser.SimpleEGLConfigChooser;
-
-
- // Original code provided by Robert Green
- // http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers
- public class GLWallpaperService extends WallpaperService {
- private static final String TAG = "GLWallpaperService";
-
- @Override
- public Engine onCreateEngine() {
- return new GLEngine();
- }
-
- public class GLEngine extends Engine {
- public final static int RENDERMODE_WHEN_DIRTY = 0;
- public final static int RENDERMODE_CONTINUOUSLY = 1;
-
- private GLThread mGLThread;
- private EGLConfigChooser mEGLConfigChooser;
- private EGLContextFactory mEGLContextFactory;
- private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
- private GLWrapper mGLWrapper;
- private int mDebugFlags;
-
- public GLEngine() {
- super();
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- if (visible) {
- onResume();
- } else {
- onPause();
- }
- super.onVisibilityChanged(visible);
- }
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
- // Log.d(TAG, "GLEngine.onCreate()");
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- // Log.d(TAG, "GLEngine.onDestroy()");
- mGLThread.requestExitAndWait();
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- // Log.d(TAG, "onSurfaceChanged()");
- mGLThread.onWindowResize(width, height);
- super.onSurfaceChanged(holder, format, width, height);
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- Log.d(TAG, "onSurfaceCreated()");
- mGLThread.surfaceCreated(holder);
- super.onSurfaceCreated(holder);
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- Log.d(TAG, "onSurfaceDestroyed()");
- mGLThread.surfaceDestroyed();
- super.onSurfaceDestroyed(holder);
- }
-
- /**
- * An EGL helper class.
- */
- public void setGLWrapper(GLWrapper glWrapper) {
- mGLWrapper = glWrapper;
- }
-
- public void setDebugFlags(int debugFlags) {
- mDebugFlags = debugFlags;
- }
-
- public int getDebugFlags() {
- return mDebugFlags;
- }
-
- public void setRenderer(Renderer renderer) {
- checkRenderThreadState();
- if (mEGLConfigChooser == null) {
- mEGLConfigChooser = new SimpleEGLConfigChooser(true);
- }
- if (mEGLContextFactory == null) {
- mEGLContextFactory = new DefaultContextFactory();
- }
- if (mEGLWindowSurfaceFactory == null) {
- mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
- }
- mGLThread = new GLThread(renderer, mEGLConfigChooser, mEGLContextFactory, mEGLWindowSurfaceFactory, mGLWrapper);
- mGLThread.start();
- }
-
- public void setEGLContextFactory(EGLContextFactory factory) {
- checkRenderThreadState();
- mEGLContextFactory = factory;
- }
-
- public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) {
- checkRenderThreadState();
- mEGLWindowSurfaceFactory = factory;
- }
-
- public void setEGLConfigChooser(EGLConfigChooser configChooser) {
- checkRenderThreadState();
- mEGLConfigChooser = configChooser;
- }
-
- public void setEGLConfigChooser(boolean needDepth) {
- setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth));
- }
-
- public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, int depthSize,
- int stencilSize) {
- setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, blueSize, alphaSize, depthSize,
- stencilSize));
- }
-
- public void setRenderMode(int renderMode) {
- mGLThread.setRenderMode(renderMode);
- }
-
- public int getRenderMode() {
- return mGLThread.getRenderMode();
- }
-
- public void requestRender() {
- mGLThread.requestRender();
- }
-
- public void onPause() {
- mGLThread.onPause();
- }
-
- public void onResume() {
- mGLThread.onResume();
- }
-
- public void queueEvent(Runnable r) {
- mGLThread.queueEvent(r);
- }
-
- private void checkRenderThreadState() {
- if (mGLThread != null) {
- throw new IllegalStateException("setRenderer has already been called for this instance.");
- }
- }
- }
-
- public interface Renderer {
-
- public void onSurfaceCreated(GL10 gl, EGLConfig config);
-
- public void onSurfaceChanged(GL10 gl, int width, int height);
-
- public void onDrawFrame(GL10 gl);
- }
- }
-
- class LogWriter extends Writer {
- private StringBuilder mBuilder = new StringBuilder();
-
- @Override
- public void close() {
- flushBuilder();
- }
-
- @Override
- public void flush() {
- flushBuilder();
- }
-
- @Override
- public void write(char[] buf, int offset, int count) {
- for (int i = 0; i < count; i++) {
- char c = buf[offset + i];
- if (c == "
") {
- flushBuilder();
- } else {
- mBuilder.append(c);
- }
- }
- }
-
- private void flushBuilder() {
- if (mBuilder.length() > 0) {
- Log.v("GLSurfaceView", mBuilder.toString());
- mBuilder.delete(0, mBuilder.length());
- }
- }
- }
-
- // ----------------------------------------------------------------------
-
- /**
- * An interface for customizing the eglCreateContext and eglDestroyContext calls.
- *
-
- * This interface must be implemented by clients wishing to call
- * {@link GLWallpaperService#setEGLContextFactory(EGLContextFactory)}
- */
- interface EGLContextFactory {
- EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig);
-
- void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context);
- }
-
- class DefaultContextFactory implements EGLContextFactory {
-
- public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) {
- return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null);
- }
-
- public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) {
- egl.eglDestroyContext(display, context);
- }
- }
-
- /**
- * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls.
- *
-
- * This interface must be implemented by clients wishing to call
- * {@link GLWallpaperService#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)}
- */
- interface EGLWindowSurfaceFactory {
- EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config, Object nativeWindow);
-
- void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface);
- }
-
- class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory {
-
- public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay
- display, EGLConfig config, Object nativeWindow) {
- // this is a bit of a hack to work around Droid init problems - if you don"t have this, it"ll get hung up on orientation changes
- EGLSurface eglSurface = null;
- while (eglSurface == null) {
- try {
- eglSurface = egl.eglCreateWindowSurface(display,
- config, nativeWindow, null);
- } catch (Throwable t) {
- } finally {
- if (eglSurface == null) {
- try {
- Thread.sleep(10);
- } catch (InterruptedException t) {
- }
- }
- }
- }
- return eglSurface;
- }
-
- public void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface) {
- egl.eglDestroySurface(display, surface);
- }
- }
-
- interface GLWrapper {
- /**
- * Wraps a gl interface in another gl interface.
- *
- * @param gl
- * a GL interface that is to be wrapped.
- * @return either the input argument or another GL object that wraps the input argument.
- */
- GL wrap(GL gl);
- }
-
- class EglHelper {
-
- private EGL10 mEgl;
- private EGLDisplay mEglDisplay;
- private EGLSurface mEglSurface;
- private EGLContext mEglContext;
- EGLConfig mEglConfig;
-
- private EGLConfigChooser mEGLConfigChooser;
- private EGLContextFactory mEGLContextFactory;
- private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory;
- private GLWrapper mGLWrapper;
-
- public EglHelper(EGLConfigChooser chooser, EGLContextFactory contextFactory,
- EGLWindowSurfaceFactory surfaceFactory, GLWrapper wrapper) {
- this.mEGLConfigChooser = chooser;
- this.mEGLContextFactory = contextFactory;
- this.mEGLWindowSurfaceFactory = surfaceFactory;
- this.mGLWrapper = wrapper;
- }
-
- /**
- * Initialize EGL for a given configuration spec.
- *
- * @param configSpec
- */
- public void start() {
- // Log.d("EglHelper" + instanceId, "start()");
- if (mEgl == null) {
- // Log.d("EglHelper" + instanceId, "getting new EGL");
- /*
- * Get an EGL instance
- */
- mEgl = (EGL10) EGLContext.getEGL();
- } else {
- // Log.d("EglHelper" + instanceId, "reusing EGL");
- }
-
- if (mEglDisplay == null) {
- // Log.d("EglHelper" + instanceId, "getting new display");
- /*
- * Get to the default display.
- */
- mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
- } else {
- // Log.d("EglHelper" + instanceId, "reusing display");
- }
-
- if (mEglConfig == null) {
- // Log.d("EglHelper" + instanceId, "getting new config");
- /*
- * We can now initialize EGL for that display
- */
- int[] version = new int[2];
-  
|