blob: b16517c38ed6bb15ffe23ae9021e84e62fcaa412 [file] [log] [blame]
/*
* Copyright (C) 2014 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.camera.gl;
import android.graphics.SurfaceTexture;
import com.android.camera.gl.FrameDistributor;
import com.android.camera.gl.FrameDistributor.FrameConsumer;
/**
* Consumes frames from a {@link FrameDistributor} and passes them into a
* SurfaceTexture.
*/
//TODO: Document this class a bit more and add a test for this class.
public class SurfaceTextureConsumer implements FrameConsumer {
private SurfaceTexture mSurfaceTexture;
private final float[] mTransform = new float[16];
private CopyShader mCopyShader;
private RenderTarget mTarget;
private int mWidth;
private int mHeight;
@Override
public synchronized void onStart() {}
@Override
public synchronized void onNewFrameAvailable(FrameDistributor frameDistributor,
long timestampNs) {
if (mSurfaceTexture == null) {
throw new IllegalStateException("Receiving frames without a SurfaceTexture!");
}
if (mTarget == null) {
mTarget = frameDistributor.getRenderTarget().forSurfaceTexture(mSurfaceTexture);
}
renderFrameToTarget(frameDistributor);
}
@Override
public synchronized void onStop() {
releaseResources();
}
public synchronized SurfaceTexture getSurfaceTexture() {
return mSurfaceTexture;
}
public synchronized void setSurfaceTexture(SurfaceTexture surfaceTexture,
int width,
int height) {
mSurfaceTexture = surfaceTexture;
mWidth = width;
mHeight = height;
releaseResources();
}
public synchronized void setSize(int width, int height) {
mWidth = width;
mHeight = height;
}
public synchronized void setDefaultBufferSize(int width, int height) {
if (mSurfaceTexture != null) {
mSurfaceTexture.setDefaultBufferSize(width, height);
}
}
public synchronized int getWidth() {
return mWidth;
}
public synchronized int getHeight() {
return mHeight;
}
private void releaseResources() {
if (mTarget != null) {
mTarget.close();
mTarget = null;
}
if (mCopyShader != null) {
mCopyShader.release();
mCopyShader = null;
}
}
private void renderFrameToTarget(FrameDistributor frameDistributor) {
CopyShader shader = getCopyShader();
int texture = GLToolbox.generateTexture();
frameDistributor.acquireNextFrame(texture, mTransform);
try {
shader.setTransform(mTransform);
shader.renderTextureToTarget(texture, mTarget, mWidth, mHeight);
} finally {
frameDistributor.releaseFrame();
GLToolbox.deleteTexture(texture);
}
mTarget.swapBuffers();
}
private CopyShader getCopyShader() {
if (mCopyShader == null) {
mCopyShader = CopyShader.compileNewExternalShader();
}
return mCopyShader;
}
}