I'm trying to create video wallpaper
using MediaPlayer
. Also I want to use own shaders to apply visual effects on video. I've figured out that it is possible if use TextureView
. Here is an example which works perfect, but for Activity
only. I need the same functionality for WallpaperService
. So, I tried to replace GLSurfaceView
by GLTextureView class. I had a class which works great:
public final class GLWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}
private final class WallpaperEngine extends Engine implements
SharedPreferences.OnSharedPreferenceChangeListener {
// Slightly modified GLSurfaceView.
private WallpaperGLSurfaceView mGLSurfaceView;
private SharedPreferences mPreferences;
private EngineCore mRenderer;
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
mRenderer = new EngineCore();
mRenderer.setContext(GLWallpaperService.this);
mGLSurfaceView = new WallpaperGLSurfaceView(GLWallpaperService.this);
mGLSurfaceView.setEGLContextClientVersion(2);
mGLSurfaceView.setRenderer(mRenderer);
mGLSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
mGLSurfaceView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mGLSurfaceView.onDestroy();
mGLSurfaceView = null;
mRenderer = null;
}
@Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (visible) {
mGLSurfaceView.onResume();
} else {
mGLSurfaceView.onPause();
}
}
/**
* Lazy as I am, I din't bother using GLWallpaperService (found on
* GitHub) project for wrapping OpenGL functionality into my wallpaper
* service. Instead I am using GLSurfaceView and trick it into hooking
* into Engine provided SurfaceHolder instead of SurfaceView provided
* one GLSurfaceView extends.
*/
private final class WallpaperGLSurfaceView extends GLSurfaceView {
public WallpaperGLSurfaceView(Context context) {
super(context);
}
@Override
public SurfaceHolder getHolder() {
return WallpaperEngine.this.getSurfaceHolder();
}
/**
* Should be called once underlying Engine is destroyed. Calling
* onDetachedFromWindow() will stop rendering thread which is lost
* otherwise.
*/
public void onDestroy() {
super.onDetachedFromWindow();
}
}
}
}
And I got new one by replacing GLSurfaceView on GLTextureView:
public final class GLTextureWallpaperService extends WallpaperService {
@Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}
private final class WallpaperEngine extends Engine {
// Slightly modified GLSurfaceView.
private WallpaperGLTextureView mGLTextureView;
private EngineRenderer mRenderer;
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
mRenderer = new EngineRenderer();
mRenderer.setContext(GLTextureWallpaperService.this);
mGLTextureView = new WallpaperGLTextureView(GLTextureWallpaperService.this);
mGLTextureView.setEGLContextClientVersion(2);
mGLTextureView.setRenderer(mRenderer);
mGLTextureView.setRenderMode(GLTextureView.RENDERMODE_CONTINUOUSLY);
mGLTextureView.onPause();
}
@Override
public void onDestroy() {
super.onDestroy();
mGLTextureView.onDestroy();
mGLTextureView = null;
mRenderer = null;
}
@Override
public void onVisibilityChanged(boolean visible) {
super.onVisibilityChanged(visible);
if (visible) {
mGLTextureView.onResume();
} else {
mGLTextureView.onPause();
}
}
/**
* Lazy as I am, I din't bother using GLWallpaperService (found on
* GitHub) project for wrapping OpenGL functionality into my wallpaper
* service. Instead I am using GLSurfaceView and trick it into hooking
* into Engine provided SurfaceHolder instead of SurfaceView provided
* one GLSurfaceView extends.
*/
private final class WallpaperGLTextureView extends GLTextureView {
public WallpaperGLTextureView(Context context) {
super(context);
}
//THIS IS NOT EXIST IN GLTEXTUREVIEW CLASS!!!
/*
@Override
public SurfaceHolder getHolder() {
Log.e("getHolder", "getHolder");
return WallpaperEngine.this.getSurfaceHolder();
}
*/
//TRIED TO CHANGE getHolder() BY THIS ONE - NO RESULTS!
@Override
public SurfaceTexture getSurfaceTexture() {
Log.e("getSurfaceTexture", "getSurfaceTexture");
return (SurfaceTexture) WallpaperEngine.this.getSurfaceHolder();
}
public void onDestroy() {
super.onDetachedFromWindow();
}
}
}
}
Renderer class:
public class EngineRenderer implements GLTextureView.Renderer {
Context context;
public void setContext(Context context){
this.context=context;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.e("ds", "-onSurfaceCreated--");
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.e("ds", "-onSurfaceCreated--");
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(1, 0, 0, 1);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
@Override
public void onSurfaceDestroyed(GL10 gl) {
}
}
I don't get any errors, just black screen. Renderer class is not drawn! It seems to me that GLTextureView
doesn't have getHolder()
function.
What should I do? Maybe there is another way to implement my goal.