├── .gitignore
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── example
│ │ └── copygpu
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── com
│ │ │ └── example
│ │ │ └── copygpu
│ │ │ ├── GLCopyJni.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MyGLRenderer.java
│ │ │ ├── Picture.java
│ │ │ ├── gpu
│ │ │ ├── EGLManager.java
│ │ │ ├── EGLUtil.java
│ │ │ ├── GLUtil.java
│ │ │ └── RenderThread.java
│ │ │ └── view
│ │ │ └── MySurfaceView.java
│ ├── jni
│ │ ├── Android.mk
│ │ ├── GPUIPCommon.cpp
│ │ ├── GPUIPCommon.h
│ │ ├── GraphicBufferEx.cpp
│ │ ├── GraphicBufferEx.h
│ │ ├── NubiaGLCopy.cpp
│ │ ├── NubiaGLCopy.h
│ │ ├── Utils.cpp
│ │ └── Utils.h
│ └── res
│ │ ├── drawable-v24
│ │ └── ic_launcher_foreground.xml
│ │ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── drawable
│ │ └── ic_launcher_background.xml
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── raw
│ │ ├── texture_2d_fragment_shader.glsl
│ │ ├── texture_oes2oes_fragment_shader.glsl
│ │ ├── texture_oes_fragment_shader.glsl
│ │ └── texture_vertex_shader.glsl
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── example
│ └── copygpu
│ └── ExampleUnitTest.java
├── build.gradle
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 26
5 | defaultConfig {
6 | applicationId "com.example.copygpu"
7 | minSdkVersion 26
8 | targetSdkVersion 26
9 | versionCode 1
10 | versionName "1.0"
11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | ndk{
18 | abiFilters "arm64-v8a"
19 | }
20 | }
21 | }
22 | externalNativeBuild {
23 | ndkBuild {
24 | path 'src/main/jni/Android.mk'
25 | }
26 | }
27 | }
28 |
29 | dependencies {
30 | implementation fileTree(dir: 'libs', include: ['*.jar'])
31 | implementation 'com.android.support.constraint:constraint-layout:1.1.2'
32 | testImplementation 'junit:junit:4.12'
33 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
34 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
35 | }
36 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/example/copygpu/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumented test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("com.example.copygpu", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/GLCopyJni.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | /*
4 | * Author : chenguoting on 2018-8-1 17:23
5 | * Email : chen.guoting@nubia.com
6 | * Company : NUBIA TECHNOLOGY CO., LTD.
7 | */
8 | public class GLCopyJni {
9 | static {
10 | System.loadLibrary("NubiaGLCopy");
11 | }
12 | private long mHandler;
13 |
14 | public GLCopyJni(int width, int height, int texture) {
15 | mHandler = initHardwareBuffer(width, height, texture);
16 | }
17 |
18 | public void release() {
19 | releaseHardwareBuffer(mHandler);
20 | }
21 |
22 | public byte[] getBuffer() {
23 | return getBuffer(mHandler);
24 | }
25 |
26 | public void setBuffer(byte[] buffer) {
27 | setBuffer(mHandler, buffer);
28 | }
29 |
30 | private static native long initHardwareBuffer(int width, int height, int texture);
31 | private static native void releaseHardwareBuffer(long handler);
32 | private static native byte[] getBuffer(long handler);
33 | private static native void setBuffer(long handler, byte[] buffer);
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.pm.PackageManager;
6 | import android.graphics.SurfaceTexture;
7 | import android.hardware.Camera;
8 | import android.os.Bundle;
9 | import android.util.Log;
10 |
11 | import com.example.copygpu.view.MySurfaceView;
12 |
13 | import java.io.IOException;
14 | import java.util.ArrayList;
15 |
16 | public class MainActivity extends Activity {
17 | private final static String TAG = "GPUActivity";
18 | private SurfaceTexture mSurfaceTexture = new SurfaceTexture(0);
19 | private MySurfaceView mSurfaceView;
20 | private Camera mCamera;
21 | private int mCameraId = 0;
22 | private Camera.Parameters mParameters;
23 | private final static int PERMISSION_REQUEST_CODE = 1234;
24 | private boolean mIsPause = true;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | Log.i(TAG, "onCreate");
30 | setContentView(R.layout.activity_main);
31 | initView();
32 | checkPermiss();
33 | }
34 |
35 | @Override
36 | protected void onResume() {
37 | super.onResume();
38 | Log.i(TAG, "onResume");
39 | mIsPause = false;
40 | openCamera();
41 | }
42 |
43 | @Override
44 | protected void onPause() {
45 | Log.i(TAG, "onPause");
46 | closeCamera();
47 | mIsPause = true;
48 | super.onPause();
49 | }
50 |
51 | private void initView() {
52 | mSurfaceView = (MySurfaceView)findViewById(R.id.surfaceView);
53 | mSurfaceView.addRenderer(new MyGLRenderer(this, mSurfaceTexture));
54 | }
55 |
56 | private void checkPermiss() {
57 | ArrayList list = new ArrayList<>();
58 | if (checkSelfPermission(Manifest.permission.CAMERA)
59 | != PackageManager.PERMISSION_GRANTED) {
60 | list.add(Manifest.permission.CAMERA);
61 | }
62 | if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
63 | != PackageManager.PERMISSION_GRANTED) {
64 | list.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
65 | }
66 | if(!list.isEmpty()) {
67 | requestPermissions(list.toArray(new String[list.size()]), PERMISSION_REQUEST_CODE);
68 | }
69 | }
70 |
71 | private boolean openCamera() {
72 | if(mIsPause || mCamera != null) {
73 | return false;
74 | }
75 | try {
76 | Log.i(TAG, "openCamera E");
77 | mCamera = Camera.open(mCameraId);
78 | mCamera.setPreviewTexture(mSurfaceTexture);
79 | mParameters = mCamera.getParameters();
80 | mParameters.setPreviewSize(1920, 1080);
81 | mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
82 | mCamera.setParameters(mParameters);
83 | mCamera.setDisplayOrientation(90);
84 | mCamera.startPreview();
85 | Log.i(TAG, "openCamera X");
86 | } catch (IOException e) {
87 | Log.e(TAG, e.getMessage());
88 | return false;
89 | }
90 | return true;
91 | }
92 |
93 | private void closeCamera() {
94 | if(mCamera == null) {
95 | return;
96 | }
97 | mCamera.release();
98 | mCamera = null;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/MyGLRenderer.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | import android.content.Context;
4 | import android.graphics.SurfaceTexture;
5 | import android.opengl.GLES11Ext;
6 | import android.opengl.GLES20;
7 | import android.util.Log;
8 |
9 | import com.example.copygpu.gpu.GLUtil;
10 | import com.example.copygpu.view.MySurfaceView;
11 |
12 | import java.io.FileOutputStream;
13 | import java.io.IOException;
14 | import java.util.Arrays;
15 |
16 | public class MyGLRenderer implements MySurfaceView.Renderer {
17 | private final static String TAG = "GPURenderer";
18 | private Context mContext;
19 | private int mPreviewTextureId = -1;
20 | private SurfaceTexture mPreviewTexture;
21 | private GLCopyJni mGLCopyJni;
22 | private int mOESTextureId = -1;
23 | private Picture mPreview;
24 | private Picture m2DPicture;
25 | private Picture mOesPicture;
26 | private Picture mOes2OesPicture;
27 | private int[] mFrameBuffer;
28 | private int m2DTextureId = -1;
29 |
30 |
31 | public MyGLRenderer(Context c, SurfaceTexture texture) {
32 | mContext = c;
33 | mPreviewTexture = texture;
34 | }
35 |
36 | @Override
37 | public void onSurfaceCreated() {
38 | Log.i(TAG, "onSurfaceCreated");
39 | GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
40 |
41 | mPreviewTextureId = GLUtil.getOneTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
42 | mPreviewTexture.detachFromGLContext();
43 | mPreviewTexture.attachToGLContext(mPreviewTextureId);
44 | mPreview = new Picture(mContext.getResources(), R.raw.texture_vertex_shader, R.raw.texture_oes_fragment_shader,
45 | mPreviewTextureId, GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
46 | mOes2OesPicture = new Picture(mContext.getResources(), R.raw.texture_vertex_shader, R.raw.texture_oes2oes_fragment_shader,
47 | mPreviewTextureId, GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
48 |
49 | mOESTextureId = GLUtil.getOneTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
50 | mGLCopyJni = new GLCopyJni(1080, 1920, mOESTextureId);
51 | mOesPicture = new Picture(mContext.getResources(), R.raw.texture_vertex_shader, R.raw.texture_oes_fragment_shader,
52 | mOESTextureId, GLES11Ext.GL_TEXTURE_EXTERNAL_OES);
53 |
54 | m2DTextureId = GLUtil.getOneTexture(GLES20.GL_TEXTURE_2D);
55 | GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 1080, 1920, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
56 | m2DPicture = new Picture(mContext.getResources(), R.raw.texture_vertex_shader, R.raw.texture_2d_fragment_shader,
57 | m2DTextureId, GLES20.GL_TEXTURE_2D);
58 | }
59 |
60 | @Override
61 | public void onSurfaceChanged(int width, int height) {
62 | Log.i(TAG, "onSurfaceChanged "+width+" "+height);
63 | GLES20.glViewport(0, 0, width, height);
64 | }
65 |
66 | @Override
67 | public void onSurfaceDraw() {
68 | // Redraw background color
69 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
70 |
71 | mPreviewTexture.updateTexImage();
72 | //直接将预览绘制到屏幕
73 | //mPreview.draw();
74 |
75 | //将一个YUV数据放到OES纹理,再将纹理绘制到屏幕
76 | /*byte[] bytes = new byte[1080*1920*3/2];
77 | Arrays.fill(bytes, (byte)127);
78 | mGLCopyJni.setBuffer(bytes);
79 | mOesPicture.draw();*/
80 |
81 | //将预览绘制到一个2D纹理,再将纹理绘制到屏幕
82 | /*beginRenderTarget(GLES20.GL_TEXTURE_2D, m2DTextureId);
83 | GLUtil.checkGlError();
84 | mPreview.draw();
85 | GLUtil.checkGlError();
86 | endRenderTarget();
87 | m2DPicture.draw();*/
88 |
89 | long start = System.currentTimeMillis();
90 | //将预览绘制到一个OES纹理,将纹理的数据拷贝出来并保存,再将纹理绘制到屏幕
91 | beginRenderTarget(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mOESTextureId);
92 | GLUtil.checkGlError();
93 | mOes2OesPicture.draw();
94 | GLUtil.checkGlError();
95 | GLES20.glFinish();
96 | endRenderTarget();
97 | yuv = mGLCopyJni.getBuffer();
98 | long end = System.currentTimeMillis();
99 | time = time * 0.8f + (end-start) * 0.2f;
100 | Log.i(TAG, "time "+time);
101 | save(yuv);
102 | mOesPicture.draw();
103 | }
104 | float time = 0;
105 | byte[] yuv;
106 |
107 | @Override
108 | public void onSurfaceDestroyed() {
109 | Log.i(TAG, "onSurfaceDestroyed");
110 | mPreviewTexture.detachFromGLContext();
111 | GLES20.glDeleteTextures(1, new int[]{mPreviewTextureId}, 0);
112 | mPreviewTextureId = -1;
113 |
114 | mGLCopyJni.release();
115 | GLES20.glDeleteTextures(1, new int[]{mOESTextureId}, 0);
116 | mOESTextureId = -1;
117 |
118 | if(mFrameBuffer != null) {
119 | GLES20.glDeleteFramebuffers(1, mFrameBuffer, 0);
120 | }
121 | }
122 |
123 | public void beginRenderTarget(int target, int textureId){
124 | if(mFrameBuffer == null){
125 | mFrameBuffer = new int[1];
126 | GLES20.glGenFramebuffers(1, mFrameBuffer, 0);
127 | GLUtil.checkGlError();
128 | }
129 |
130 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFrameBuffer[0]);
131 | GLUtil.checkGlError();
132 |
133 | GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
134 | target, textureId, 0);
135 | GLUtil.checkFramebufferStatus();
136 | }
137 |
138 | public void endRenderTarget(){
139 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
140 | GLUtil.checkGlError();
141 | }
142 |
143 | private static void save(byte[] yuv) {
144 | try {
145 | String pathName = "/sdcard/hw.yuv";
146 | FileOutputStream outputStream = new FileOutputStream(pathName);
147 | outputStream.write(yuv);
148 | outputStream.close();
149 | } catch (IOException e) {
150 | e.printStackTrace();
151 | }
152 | }
153 |
154 | }
155 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/Picture.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | import android.content.res.Resources;
4 | import android.opengl.GLES20;
5 | import android.opengl.Matrix;
6 |
7 | import com.example.copygpu.gpu.GLUtil;
8 |
9 | import java.nio.FloatBuffer;
10 |
11 | /*
12 | * Author : chenguoting on 2018-7-10 10:24
13 | * Email : chen.guoting@nubia.com
14 | * Company : NUBIA TECHNOLOGY CO., LTD.
15 | */
16 | public class Picture {
17 | private final int mProgram;
18 | private int mPositionHandle;
19 | private int mTextureCoordHandle;
20 | private int mMVPMatrixHandle;
21 | private int mSTMatrixHandle;
22 | private int mTextureHandle;
23 |
24 | private float[] mMVPMatrix = new float[16];
25 | private float[] mSTMatrix = new float[16];
26 | private final int vertexCount = rectCoords.length / COORDS_PER_VERTEX;
27 | private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
28 | private FloatBuffer vertexBuffer;
29 | private FloatBuffer textureCoordBuffer;
30 | private int mTextureID;
31 | private int mTextureTarget;
32 |
33 | // number of coordinates per vertex in this array
34 | static final int COORDS_PER_VERTEX = 3;
35 |
36 | static final float rectCoords[] = {
37 | -1, 1, 0, //左上
38 | 1, 1, 0, //右上
39 | -1, -1, 0, //左下
40 | 1, -1, 0 //右下
41 | };
42 |
43 | static final float textureCoords[] = {
44 | 0, 0,
45 | 1, 0,
46 | 0, 1,
47 | 1, 1
48 | };
49 |
50 | public Picture(Resources res, int vertexId, int fragmentId, int textureId, int target) {
51 | Matrix.setIdentityM(mMVPMatrix, 0);
52 | Matrix.setIdentityM(mSTMatrix, 0);
53 |
54 | vertexBuffer = GLUtil.arrayToBuffer(rectCoords);
55 | textureCoordBuffer = GLUtil.arrayToBuffer(textureCoords);
56 |
57 | mTextureID = textureId;
58 | mTextureTarget = target;
59 |
60 | int vertexShader = GLUtil.loadShader(GLES20.GL_VERTEX_SHADER,
61 | GLUtil.readRawFile(res, vertexId));
62 | int fragmentShader = GLUtil.loadShader(GLES20.GL_FRAGMENT_SHADER,
63 | GLUtil.readRawFile(res, fragmentId));
64 | mProgram = GLUtil.createProgram(vertexShader, fragmentShader);
65 |
66 | mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
67 | mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
68 | mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
69 | mSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
70 | mTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTextureSampler");
71 |
72 | }
73 |
74 |
75 | public void draw() {
76 | // Add program to OpenGL ES environment
77 | GLES20.glUseProgram(mProgram);
78 |
79 | // Enable a handle to the rect vertices
80 | GLES20.glEnableVertexAttribArray(mPositionHandle);
81 | // Prepare the rect coordinate data
82 | GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
83 | GLES20.GL_FLOAT, false,
84 | vertexStride, vertexBuffer);
85 |
86 | GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
87 | GLES20.glVertexAttribPointer(mTextureCoordHandle, 2,
88 | GLES20.GL_FLOAT, false,
89 | 2*4, textureCoordBuffer);
90 |
91 | GLES20.glActiveTexture(GLES20.GL_TEXTURE3);
92 | GLES20.glBindTexture(mTextureTarget, mTextureID);
93 | GLES20.glUniform1i(mTextureHandle, 3);
94 |
95 | GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
96 | GLES20.glUniformMatrix4fv(mSTMatrixHandle, 1, false, mSTMatrix, 0);
97 |
98 | // Draw the triangle
99 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
100 |
101 | // Disable vertex array
102 | GLES20.glDisableVertexAttribArray(mPositionHandle);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/gpu/EGLManager.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu.gpu;
2 | /*
3 | * Author : jinrong on 2017-7-21 9:16
4 | * Email : jin.rong1@nubia.com
5 | * Company : NUBIA TECHNOLOGY CO., LTD.
6 | */
7 |
8 | import android.opengl.EGL14;
9 | import android.opengl.EGLConfig;
10 | import android.opengl.EGLContext;
11 | import android.opengl.EGLDisplay;
12 | import android.opengl.EGLSurface;
13 | import android.view.SurfaceHolder;
14 |
15 | public class EGLManager {
16 |
17 |
18 | private EGLDisplay mEglDisplay;
19 | private EGLConfig mEGLConfig;
20 | private EGLContext mEGLContext;
21 | private EGLSurface mEglWindowSurface;
22 | private EGLSurface mEglSnapshotSurface = null;
23 | private State mState = State.UNINIT;
24 | public enum State{
25 | UNINIT,
26 | INITED,
27 | SURFACED,
28 | REGISTERD,
29 | UNREGISTERD,
30 | }
31 |
32 | public EGLManager() throws Exception {
33 | mEglDisplay = EGLUtil.getEGLDisplay();
34 | mEGLConfig = EGLUtil.getEGLConfig(mEglDisplay);
35 | mEGLContext = EGLUtil.getEGLContext(mEglDisplay, mEGLConfig);
36 | mState = State.INITED;
37 | }
38 |
39 | public void release() {
40 | if (mState.ordinal() > State.UNINIT.ordinal()) {
41 | EGL14.eglDestroyContext(mEglDisplay, mEGLContext);
42 | mEGLContext = null;
43 | if(mEglSnapshotSurface != null){
44 | EGL14.eglDestroySurface(mEglDisplay, mEglSnapshotSurface);
45 | mEglSnapshotSurface=null;
46 | }
47 | EGL14.eglTerminate(mEglDisplay);
48 | }
49 |
50 | mEglDisplay = null;
51 | mEGLConfig = null;
52 |
53 | mState = State.UNINIT;
54 | }
55 |
56 | public void swapBuffer(){
57 | EGL14.eglSwapBuffers(mEglDisplay, mEglWindowSurface);
58 | }
59 |
60 | public boolean registerContext(){
61 | return EGL14.eglMakeCurrent(mEglDisplay, mEglWindowSurface,
62 | mEglWindowSurface, mEGLContext);
63 | }
64 |
65 | public void unregisterContext(){
66 | EGL14.eglMakeCurrent(mEglDisplay, EGL14.EGL_NO_SURFACE,
67 | EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT);
68 | }
69 |
70 | public EGLSurface createWindowSurface(SurfaceHolder surface) throws Exception {
71 | int[] surfaceAttribs = { EGL14.EGL_NONE };
72 | mEglWindowSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEGLConfig, surface, surfaceAttribs, 0);
73 | int error = EGL14.eglGetError();
74 | if(error != EGL14.EGL_SUCCESS){
75 | throw new Exception("fail to get window surface error: "+error);
76 | }
77 | return mEglWindowSurface;
78 | }
79 |
80 | public void releaseWindowSurface() {
81 | if(mEglWindowSurface != null) {
82 | EGL14.eglDestroySurface(mEglDisplay, mEglWindowSurface);
83 | mEglWindowSurface=null;
84 | }
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/gpu/EGLUtil.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu.gpu;
2 | /*
3 | * Author : jinrong on 2017-7-21 9:16
4 | * Email : jin.rong1@nubia.com
5 | * Company : NUBIA TECHNOLOGY CO., LTD.
6 | */
7 |
8 | import android.opengl.EGL14;
9 | import android.opengl.EGLConfig;
10 | import android.opengl.EGLContext;
11 | import android.opengl.EGLDisplay;
12 | import android.util.Log;
13 |
14 | public class EGLUtil {
15 | private final static String TAG = "EGLUtil";
16 | public static final int EGL_RECORDABLE_ANDROID = 0x3142;
17 |
18 | public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
19 | for(int s=srcPos,d=dstPos,i=0; s mRendererList = new ArrayList();
29 |
30 |
31 | public RenderThread(SurfaceHolder holder, ArrayList list){
32 | super("Nubia Render Thread");
33 | mWindowSurfaceHolder = holder;
34 | mRendererList = list;
35 | }
36 |
37 | public void setSurfaceSize(int w, int h) {
38 | width = w;
39 | height = h;
40 | isSurfaceChanged = true;
41 | synchronized (this) {
42 | notify();
43 | }
44 | }
45 |
46 | private void notifyRendererCreated() {
47 | if(mRendererList.isEmpty()) {
48 | return;
49 | }
50 | MySurfaceView.Renderer[] renderers = mRendererList.toArray(new MySurfaceView.Renderer[mRendererList.size()]);
51 | for(MySurfaceView.Renderer renderer : renderers) {
52 | renderer.onSurfaceCreated();
53 | }
54 | }
55 | private void notifyRendererChanged() {
56 | if(mRendererList.isEmpty()) {
57 | return;
58 | }
59 | MySurfaceView.Renderer[] renderers = mRendererList.toArray(new MySurfaceView.Renderer[mRendererList.size()]);
60 | for(MySurfaceView.Renderer renderer : renderers) {
61 | renderer.onSurfaceChanged(width, height);
62 | }
63 | }
64 | private void notifyRendererDraw() {
65 | if(mRendererList.isEmpty()) {
66 | return;
67 | }
68 | MySurfaceView.Renderer[] renderers = mRendererList.toArray(new MySurfaceView.Renderer[mRendererList.size()]);
69 | for(MySurfaceView.Renderer renderer : renderers) {
70 | renderer.onSurfaceDraw();
71 | }
72 | }
73 | private void notifyRendererDestroyed() {
74 | if(mRendererList.isEmpty()) {
75 | return;
76 | }
77 | MySurfaceView.Renderer[] renderers = mRendererList.toArray(new MySurfaceView.Renderer[mRendererList.size()]);
78 | for(MySurfaceView.Renderer renderer : renderers) {
79 | renderer.onSurfaceDestroyed();
80 | }
81 | }
82 |
83 | public void finish(){
84 | mFinished = true;
85 | mWindowSurfaceHolder = null;
86 | synchronized (this) {
87 | notify();
88 | }
89 | }
90 |
91 | @Override
92 | public void run() {
93 | Log.i(TAG, "thread "+getId()+" start");
94 | initEglEnv();
95 |
96 | notifyRendererCreated();
97 |
98 | while (!mFinished) {
99 | synchronized (this) {
100 | if(width == 0 || height == 0) {
101 | try {
102 | wait();
103 | } catch (InterruptedException e) {
104 | e.printStackTrace();
105 | }
106 | continue;
107 | }
108 | }
109 |
110 | if(isSurfaceChanged) {
111 | notifyRendererChanged();
112 | isSurfaceChanged = false;
113 | }
114 |
115 | notifyRendererDraw();
116 |
117 | GLES20.glFinish();
118 | mEGLManager.swapBuffer();
119 | }
120 | notifyRendererDestroyed();
121 |
122 | releaseEglEnv();
123 | Log.i(TAG, "thread "+getId()+" end");
124 | }
125 |
126 | private void initEglEnv() {
127 | try {
128 | mEGLManager = new EGLManager();
129 | mEGLManager.createWindowSurface(mWindowSurfaceHolder);
130 | mEGLManager.registerContext();
131 | isEGLSurfaceCreate = true;
132 | } catch (Exception e) {
133 | e.printStackTrace();
134 | }
135 | }
136 |
137 | private void releaseEglEnv() {
138 | Log.i(TAG, "releaseEglEnv");
139 | if(isEGLSurfaceCreate) {
140 | mEGLManager.unregisterContext();
141 | mEGLManager.releaseWindowSurface();
142 | mEGLManager.release();
143 | isEGLSurfaceCreate = false;
144 | }
145 | }
146 |
147 |
148 | }
149 |
--------------------------------------------------------------------------------
/app/src/main/java/com/example/copygpu/view/MySurfaceView.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.util.Log;
6 | import android.view.SurfaceHolder;
7 | import android.view.SurfaceView;
8 |
9 | import com.example.copygpu.gpu.RenderThread;
10 |
11 | import java.util.ArrayList;
12 |
13 | /*
14 | * Author : chenguoting on 2018-8-4 10:42
15 | * Email : chen.guoting@nubia.com
16 | * Company : NUBIA TECHNOLOGY CO., LTD.
17 | */
18 | public class MySurfaceView extends SurfaceView {
19 | private final static String TAG = "MySurfaceView";
20 | private RenderThread mRenderThread;
21 | private ArrayList mRendererList = new ArrayList();
22 |
23 | public interface Renderer {
24 | public void onSurfaceCreated();
25 | public void onSurfaceChanged(int width, int height);
26 | public void onSurfaceDraw();
27 | public void onSurfaceDestroyed();
28 | }
29 |
30 | public MySurfaceView(Context context) {
31 | this(context, null);
32 | }
33 |
34 | public MySurfaceView(Context context, AttributeSet attrs) {
35 | this(context, attrs, 0);
36 | }
37 |
38 | public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
39 | this(context, attrs, defStyleAttr, 0);
40 | }
41 |
42 | public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
43 | super(context, attrs, defStyleAttr, defStyleRes);
44 | getHolder().addCallback(Callback);
45 | }
46 |
47 | public void addRenderer(Renderer renderer) {
48 | mRendererList.add(renderer);
49 | }
50 |
51 | public void removeRenderer(Renderer renderer) {
52 | mRendererList.remove(renderer);
53 | }
54 |
55 | SurfaceHolder.Callback Callback = new SurfaceHolder.Callback() {
56 | @Override
57 | public void surfaceCreated(SurfaceHolder surfaceHolder) {
58 | Log.i(TAG, "surfaceCreated");
59 | mRenderThread = new RenderThread(surfaceHolder, mRendererList);
60 | mRenderThread.start();
61 | }
62 |
63 | @Override
64 | public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
65 | Log.i(TAG, "surfaceChanged "+i+" "+i1+" "+i2);
66 | mRenderThread.setSurfaceSize(i1, i2);
67 | }
68 |
69 | @Override
70 | public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
71 | Log.i(TAG, "surfaceDestroyed");
72 | mRenderThread.finish();
73 | }
74 | };
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH:= $(call my-dir)
2 |
3 |
4 | include $(CLEAR_VARS)
5 | LOCAL_MODULE := libNubiaGLCopy
6 |
7 | LOCAL_SRC_FILES += GraphicBufferEx.cpp \
8 | GPUIPCommon.cpp \
9 | Utils.cpp \
10 | NubiaGLCopy.cpp
11 |
12 | LOCAL_C_INCLUDES += $(LOCAL_PATH)/GPUIP \
13 | $(LOCAL_PATH)/GPUIP/Utils \
14 | $(NDK_INCLUDE)
15 |
16 | LOCAL_LDLIBS += -llog -lEGL -lGLESv3 -lnativewindow
17 | LOCAL_CPPFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES -Wno-unused-parameter
18 | include $(BUILD_SHARED_LIBRARY)
19 |
--------------------------------------------------------------------------------
/app/src/main/jni/GPUIPCommon.cpp:
--------------------------------------------------------------------------------
1 | #include "GPUIPCommon.h"
2 |
3 | void GPUIPBuffer_NV21_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer)
4 | {
5 | if ((srcBuffer->width != dstBuffer->width)
6 | || (srcBuffer->height != dstBuffer->height))
7 | {
8 | LOGE("GPUIPBuffer_NV21_COPY error. srcW = %d, dstW = %d, srcH = %d, dstH = %d\n",
9 | srcBuffer->width, dstBuffer->width, srcBuffer->height, dstBuffer->height);
10 | return;
11 | }
12 |
13 | if (srcBuffer->stride == dstBuffer->stride)
14 | {
15 | int size = srcBuffer->stride * srcBuffer->height;
16 |
17 | memcpy(dstBuffer->pY, srcBuffer->pY, size);
18 | memcpy(dstBuffer->pU, srcBuffer->pU, size / 2);
19 | }
20 | else
21 | {
22 | int i;
23 | uint8_t *pSrc;
24 | uint8_t *pDst;
25 |
26 | //LOGE("GPUIPBuffer_NV21_COPY warning! srcStride = %d, dstStride = %d",
27 | // srcBuffer->stride, dstBuffer->stride);
28 | pSrc = (uint8_t *)srcBuffer->pY;
29 | pDst = (uint8_t *)dstBuffer->pY;
30 |
31 | for (i = 0; i < srcBuffer->height; i++)
32 | {
33 | memcpy(pDst, pSrc, srcBuffer->width);
34 | pSrc += srcBuffer->stride;
35 | pDst += dstBuffer->stride;
36 | }
37 |
38 | pSrc = (uint8_t *)srcBuffer->pU;
39 | pDst = (uint8_t *)dstBuffer->pU;
40 |
41 | for (i = 0; i < srcBuffer->height / 2; i++)
42 | {
43 | memcpy(pDst, pSrc, srcBuffer->width);
44 | pSrc += srcBuffer->stride;
45 | pDst += dstBuffer->stride;
46 | }
47 | }
48 | }
49 |
50 | void GPUIPBuffer_RGB_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer)
51 | {
52 | int size;
53 |
54 | if ((srcBuffer->width != dstBuffer->width)
55 | || (srcBuffer->height != dstBuffer->height))
56 | {
57 | LOGE("GPUIPBuffer_RGB_COPY error. srcW = %d, dstW = %d, srcH = %d, dstH = %d\n",
58 | srcBuffer->width, dstBuffer->width, srcBuffer->height, dstBuffer->height);
59 | return;
60 | }
61 |
62 | if (srcBuffer->stride == dstBuffer->stride)
63 | {
64 | size = srcBuffer->stride * srcBuffer->height * 3;
65 | memcpy(dstBuffer->pY, srcBuffer->pY, size);
66 | }
67 | else
68 | {
69 | int i;
70 | int srcSize;
71 | int dstSize;
72 | uint8_t *pSrcBuffer;
73 | uint8_t *pDstBuffer;
74 |
75 | LOGE("GPUIPBuffer_RGB_COPY warning! srcStride = %d, dstStride = %d",
76 | srcBuffer->stride, dstBuffer->stride);
77 | pSrcBuffer = (uint8_t *)srcBuffer->pY;
78 | pDstBuffer = (uint8_t *)dstBuffer->pY;
79 | size = srcBuffer->width * 3;
80 | srcSize = srcBuffer->stride * 3;
81 | dstSize = dstBuffer->stride * 3;
82 |
83 | for (i = 0; i < srcBuffer->height; i++)
84 | {
85 | memcpy(pDstBuffer, pSrcBuffer, size);
86 | pSrcBuffer += srcSize;
87 | pDstBuffer += dstSize;
88 | }
89 | }
90 | }
91 |
92 | void GPUIPBuffer_RGBA_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer)
93 | {
94 | int size;
95 |
96 | if ((srcBuffer->width != dstBuffer->width)
97 | || (srcBuffer->height != dstBuffer->height))
98 | {
99 | LOGE("GPUIPBuffer_RGBA_COPY error. srcW = %d, dstW = %d, srcH = %d, dstH = %d\n",
100 | srcBuffer->width, dstBuffer->width, srcBuffer->height, dstBuffer->height);
101 | return;
102 | }
103 |
104 | if (srcBuffer->stride == dstBuffer->stride)
105 | {
106 | size = srcBuffer->stride * srcBuffer->height * 4;
107 | memcpy(dstBuffer->pY, srcBuffer->pY, size);
108 | }
109 | else
110 | {
111 | int i;
112 | int srcSize;
113 | int dstSize;
114 | uint8_t *pSrcBuffer;
115 | uint8_t *pDstBuffer;
116 |
117 | LOGE("GPUIPBuffer_RGBA_COPY warning! srcStride = %d, dstStride = %d",
118 | srcBuffer->stride, dstBuffer->stride);
119 | pSrcBuffer = (uint8_t *)srcBuffer->pY;
120 | pDstBuffer = (uint8_t *)dstBuffer->pY;
121 | size = srcBuffer->width * 4;
122 | srcSize = srcBuffer->stride * 4;
123 | dstSize = dstBuffer->stride * 4;
124 |
125 | for (i = 0; i < srcBuffer->height; i++)
126 | {
127 | memcpy(pDstBuffer, pSrcBuffer, size);
128 | pSrcBuffer += srcSize;
129 | pDstBuffer += dstSize;
130 | }
131 | }
132 | }
133 |
134 | void GPUIPBuffer_Y8U8V8_NV21(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer)
135 | {
136 | int i, j;
137 | int width, height;
138 | uint8_t *pSrcBuffer;
139 | uint8_t *pDstBuffer;
140 |
141 | if ((srcBuffer->width != dstBuffer->width)
142 | || (srcBuffer->height != dstBuffer->height))
143 | {
144 | LOGE("GPUIPBuffer_Y8U8V8_NV21 error. srcW = %d, dstW = %d, srcH = %d, dstH = %d\n",
145 | srcBuffer->width, dstBuffer->width, srcBuffer->height, dstBuffer->height);
146 | return;
147 | }
148 |
149 | width = srcBuffer->width;
150 | height = srcBuffer->height;
151 |
152 | //Y8U8V8 -> YUV
153 | for (j = 0; j < height; j++)
154 | {
155 | pSrcBuffer = (uint8_t *)srcBuffer->pY;
156 | pSrcBuffer += (srcBuffer->stride * j * 3);
157 | pDstBuffer = (uint8_t *)dstBuffer->pY;
158 | pDstBuffer += (dstBuffer->stride * j);
159 |
160 | for (i = 0; i < width; i++)
161 | {
162 | *pDstBuffer = *pSrcBuffer;
163 | pSrcBuffer += 3;
164 | pDstBuffer++;
165 | }
166 | }
167 |
168 | for (j = 0; j < height / 2; j++)
169 | {
170 | pSrcBuffer = (uint8_t *)srcBuffer->pY;
171 | pSrcBuffer += (srcBuffer->stride * j * 3 * 2 + 1);
172 | pDstBuffer = (uint8_t *)dstBuffer->pU;
173 | pDstBuffer += (dstBuffer->stride * j);
174 |
175 | for (i = 0; i < width / 2; i++)
176 | {
177 | *pDstBuffer = *pSrcBuffer;
178 | pSrcBuffer++;
179 | pDstBuffer++;
180 |
181 | *pDstBuffer = *pSrcBuffer;
182 | pSrcBuffer += 5;
183 | pDstBuffer++;
184 | }
185 | }
186 | }
187 |
188 |
--------------------------------------------------------------------------------
/app/src/main/jni/GPUIPCommon.h:
--------------------------------------------------------------------------------
1 | #ifndef GPUIP_COMMON_H
2 | #define GPUIP_COMMON_H
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #define PI 3.1415926f
11 | #define MAX_BINARY_PROGRAM_SIZE (50 * 1024)
12 |
13 | #undef LOG_TAG
14 | #define LOG_TAG "[libGPUIP]"
15 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
16 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
17 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
18 | #define PRINTF LOGI
19 |
20 | //#define JNI_INTERFACE_BOKEH
21 | //#define JNI_INTERFACE_ROTATION
22 | //#define JNI_INTERFACE_ZOOMBLUR
23 |
24 | #define USE_GRAPHIC_BUFFER
25 | //#define USE_HARDWARE_BUFFER
26 |
27 | //#define SHADER_PROGRAM_BINARY
28 |
29 | typedef enum
30 | {
31 | /*8 bit Y plane followed by 8 bit 2x2 subsampled UV planes*/
32 | PIX_FORMAT_NV12,
33 | /*8 bit Y plane followed by 8 bit 2x2 subsampled VU planes*/
34 | PIX_FORMAT_NV21,
35 | /*8 bit Y plane followed by 8 bit 2x2 subsampled U and V planes*/
36 | PIX_FORMAT_I420
37 | }PIX_FORMAT_SUPPORT;
38 |
39 | struct yuvBuffer
40 | {
41 | public:
42 | int w;
43 | int h;
44 | int pixformat;
45 | int yPitch;
46 | int uvPitch;
47 | int len;
48 | void *Y;
49 | void *U;
50 | void *V;
51 |
52 | public:
53 | yuvBuffer()
54 | : w(0)
55 | , h(0)
56 | , pixformat(PIX_FORMAT_NV21)
57 | , yPitch(0)
58 | , uvPitch(0)
59 | , len(0)
60 | , Y(NULL)
61 | , U(NULL)
62 | , V(NULL) {
63 | }
64 | };
65 |
66 | struct GPUIPBuffer
67 | {
68 | public:
69 | int width;
70 | int height;
71 | int format;
72 | int stride;
73 | int length;
74 | void *pY;
75 | void *pU;
76 | void *pV;
77 |
78 | public:
79 | GPUIPBuffer()
80 | : width(0)
81 | , height(0)
82 | , format(PIX_FORMAT_NV21)
83 | , stride(0)
84 | , length(0)
85 | , pY(NULL)
86 | , pU(NULL)
87 | , pV(NULL) {
88 | }
89 | };
90 |
91 | void GPUIPBuffer_NV21_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer);
92 | void GPUIPBuffer_RGB_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer);
93 | void GPUIPBuffer_RGBA_COPY(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer);
94 | void GPUIPBuffer_Y8U8V8_NV21(GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer);
95 |
96 |
97 | #endif
--------------------------------------------------------------------------------
/app/src/main/jni/GraphicBufferEx.cpp:
--------------------------------------------------------------------------------
1 | #include "GraphicBufferEx.h"
2 | #include "Utils.h"
3 |
4 | static const int USAGE = (AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN
5 | | AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
6 |
7 | GraphicBufferEx::GraphicBufferEx(
8 | EGLDisplay eglDisplay, EGLContext eglContext)
9 | {
10 | mEGLDisplay = eglDisplay;
11 | mEGLContext = eglContext;
12 | }
13 |
14 | int GraphicBufferEx::getWidth()
15 | {
16 | AHardwareBuffer_Desc outDesc;
17 | AHardwareBuffer_describe(mHardwareBuffer, &outDesc);
18 | return outDesc.width;
19 | }
20 |
21 | int GraphicBufferEx::getHeight()
22 | {
23 | AHardwareBuffer_Desc outDesc;
24 | AHardwareBuffer_describe(mHardwareBuffer, &outDesc);
25 | return outDesc.height;
26 | }
27 |
28 | int GraphicBufferEx::getStride()
29 | {
30 | AHardwareBuffer_Desc outDesc;
31 | AHardwareBuffer_describe(mHardwareBuffer, &outDesc);
32 | return outDesc.stride;
33 | }
34 |
35 | int GraphicBufferEx::getFormat()
36 | {
37 | AHardwareBuffer_Desc outDesc;
38 | AHardwareBuffer_describe(mHardwareBuffer, &outDesc);
39 | return outDesc.format;
40 | }
41 |
42 | void GraphicBufferEx::create(int width, int height,
43 | int textureId, int format)
44 | {
45 | //format
46 | //RGBA_8888 1
47 | //RGB_888 3
48 | //A_8 8
49 | //HAL_PIXEL_FORMAT_YCrCb_420_SP 17
50 | //HAL_PIXEL_FORMAT_YV12
51 | AHardwareBuffer_Desc buffDesc;
52 | buffDesc.width = width;
53 | buffDesc.height = height;
54 | buffDesc.layers = 1;
55 | buffDesc.format = format;
56 | buffDesc.usage = USAGE;
57 | buffDesc.stride = width;
58 | buffDesc.rfu0 = 0;
59 | buffDesc.rfu1 = 0;
60 |
61 | int err = AHardwareBuffer_allocate(&buffDesc, &mHardwareBuffer);
62 |
63 | if (0 != err)//NO_ERROR
64 | {
65 | LOGE("GraphicBufferEx HardwareBuffer create error. (NO_ERROR != err)");
66 | return;
67 | }
68 | else {
69 | LOGI("AHardwareBuffer_allocate %p", mHardwareBuffer);
70 | }
71 |
72 | EGLClientBuffer clientBuffer = eglGetNativeClientBufferANDROID(mHardwareBuffer);
73 | checkEglError("eglGetNativeClientBufferANDROID");
74 | mEGLImageKHR = eglCreateImageKHR(
75 | mEGLDisplay, mEGLContext,
76 | EGL_NATIVE_BUFFER_ANDROID, clientBuffer, 0);
77 | checkEglError("eglCreateImageKHR");
78 |
79 | if (EGL_NO_IMAGE_KHR == mEGLImageKHR)
80 | {
81 | LOGE("GraphicBufferEx create error. (EGL_NO_IMAGE_KHR == mEGLImageKHR)");
82 | return;
83 | }
84 |
85 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId);
86 | checkGlError("glBindTexture");
87 | glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)mEGLImageKHR);
88 | checkGlError("glEGLImageTargetTexture2DOES");
89 | glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
90 | checkGlError("glTexParameteri");
91 | glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
92 | checkGlError("glTexParameteri");
93 | glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
94 | }
95 |
96 | void GraphicBufferEx::destroy()
97 | {
98 | AHardwareBuffer_release(mHardwareBuffer);
99 | eglDestroyImageKHR(mEGLDisplay, mEGLImageKHR);
100 | }
101 |
102 | void GraphicBufferEx::setBuffer(GPUIPBuffer *srcBuffer)
103 | {
104 | uint8_t *pDstBuffer = NULL;
105 |
106 | if (NULL == srcBuffer)
107 | {
108 | LOGE("GraphicBufferEx setBuffer (NULL == srcBuffer)\n");
109 | return;
110 | }
111 |
112 | int err = AHardwareBuffer_lock(mHardwareBuffer, USAGE, -1, NULL, (void**)(&pDstBuffer));
113 |
114 | if (0 != err)//NO_ERROR
115 | {
116 | LOGE("GraphicBufferEx setBuffer AHardwareBuffer_lock failed. err = %d\n", err);
117 | return;
118 | }
119 |
120 | GPUIPBuffer dstBuffer;
121 |
122 | dstBuffer.width = getWidth();
123 | dstBuffer.height = getHeight();
124 | dstBuffer.format = getFormat();
125 | dstBuffer.stride = getStride();
126 | dstBuffer.pY = pDstBuffer;
127 | dstBuffer.pU = pDstBuffer + dstBuffer.stride * dstBuffer.height;
128 | dstBuffer.pV = dstBuffer.pU;
129 |
130 | switch(getFormat())
131 | {
132 | case 1://RGBA_8888
133 | {
134 | GPUIPBuffer_RGBA_COPY(srcBuffer, &dstBuffer);
135 | break;
136 | }
137 |
138 | case 3://RGB_888
139 | {
140 | GPUIPBuffer_RGB_COPY(srcBuffer, &dstBuffer);
141 | break;
142 | }
143 |
144 | case 17://HAL_PIXEL_FORMAT_YCrCb_420_SP
145 | {
146 | GPUIPBuffer_NV21_COPY(srcBuffer, &dstBuffer);
147 | break;
148 | }
149 |
150 | default:
151 | {
152 | LOGE("GraphicBufferEx setBuffer do not surpport format = %d.\n", getFormat());
153 | }
154 | }
155 |
156 | int fence = -1;
157 | err = AHardwareBuffer_unlock(mHardwareBuffer, &fence);
158 |
159 | if (0 != err)//NO_ERROR
160 | {
161 | LOGE("GraphicBufferEx setBuffer AHardwareBuffer_lock failed. err = %d\n", err);
162 | return;
163 | }
164 | }
165 |
166 | void GraphicBufferEx::getBuffer(
167 | GBDataCallBackFun pCallBackFun, GPUIPBuffer *dstBuffer)
168 | {
169 | uint8_t *pSrcBuffer = NULL;
170 |
171 | if ((NULL == pCallBackFun) || (NULL == dstBuffer))
172 | {
173 | LOGE("GraphicBufferEx getBuffer ((NULL == pCallBackFun) || (NULL == dstBuffer))\n");
174 | return;
175 | }
176 |
177 | int err = AHardwareBuffer_lock(mHardwareBuffer, USAGE, -1, NULL, (void**)(&pSrcBuffer));
178 |
179 | if (0 != err)//NO_ERROR
180 | {
181 | LOGE("GraphicBufferEx getBuffer AHardwareBuffer_lock failed. err = %d\n", err);
182 | return;
183 | }
184 |
185 | GPUIPBuffer srcBuffer;
186 |
187 | srcBuffer.width = getWidth();
188 | srcBuffer.height = getHeight();
189 | srcBuffer.format = getFormat();
190 | srcBuffer.stride = getStride();
191 | srcBuffer.pY = pSrcBuffer;
192 | srcBuffer.pU = pSrcBuffer + srcBuffer.stride * srcBuffer.height;
193 | srcBuffer.pV = srcBuffer.pU;
194 | pCallBackFun(&srcBuffer, dstBuffer);
195 |
196 | int fence = -1;
197 | err = AHardwareBuffer_unlock(mHardwareBuffer, &fence);
198 |
199 | if (0 != err)//NO_ERROR
200 | {
201 | LOGE("GraphicBufferEx getBuffer AHardwareBuffer_unlock failed. err = %d\n", err);
202 | return;
203 | }
204 | }
205 |
--------------------------------------------------------------------------------
/app/src/main/jni/GraphicBufferEx.h:
--------------------------------------------------------------------------------
1 | #ifndef GRAHIC_BUFFER_EX_H
2 | #define GRAHIC_BUFFER_EX_H
3 | #include "GPUIPCommon.h"
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | typedef void (*GBDataCallBackFun)(\
15 | GPUIPBuffer *srcBuffer, GPUIPBuffer *dstBuffer);
16 |
17 | class GraphicBufferEx {
18 | private:
19 | EGLDisplay mEGLDisplay;
20 | EGLContext mEGLContext;
21 | EGLImageKHR mEGLImageKHR;
22 | AHardwareBuffer *mHardwareBuffer;
23 |
24 | public:
25 | GraphicBufferEx(
26 | EGLDisplay eglDisplay, EGLContext eglContext);
27 | int getWidth();
28 | int getHeight();
29 | int getStride();
30 | int getFormat();
31 | void create(int width, int height,
32 | int textureId, int format);
33 | void destroy();
34 | void setBuffer(GPUIPBuffer *Buffer);
35 | void getBuffer(
36 | GBDataCallBackFun pCallBackFun, GPUIPBuffer *dstBuffer);
37 | };
38 | #endif
39 |
--------------------------------------------------------------------------------
/app/src/main/jni/NubiaGLCopy.cpp:
--------------------------------------------------------------------------------
1 | #include "NubiaGLCopy.h"
2 | #include "GraphicBufferEx.h"
3 | #include "Utils.h"
4 |
5 |
6 | JNIEXPORT jlong JNICALL
7 | Java_com_example_copygpu_GLCopyJni_initHardwareBuffer(
8 | JNIEnv*env, jclass type, jint width, jint height, jint textureId)
9 | {
10 | GraphicBufferEx* graphicBufferEx = new GraphicBufferEx(eglGetCurrentDisplay(), EGL_NO_CONTEXT);
11 | int format = 17; //HAL_PIXEL_FORMAT_YCrCb_420_SP
12 | graphicBufferEx->create(width, height, textureId, format);
13 | return (jlong)graphicBufferEx;
14 | }
15 |
16 | JNIEXPORT void JNICALL
17 | Java_com_example_copygpu_GLCopyJni_releaseHardwareBuffer(
18 | JNIEnv*env, jclass type, jlong handler)
19 | {
20 | GraphicBufferEx* graphicBufferEx = (GraphicBufferEx*)handler;
21 | graphicBufferEx->destroy();
22 | delete graphicBufferEx;
23 | }
24 |
25 | JNIEXPORT jbyteArray JNICALL
26 | Java_com_example_copygpu_GLCopyJni_getBuffer(
27 | JNIEnv*env, jclass type, jlong handler)
28 | {
29 | GraphicBufferEx* graphicBufferEx = (GraphicBufferEx*)handler;
30 | jbyteArray jYuvArray = env->NewByteArray(graphicBufferEx->getWidth()*graphicBufferEx->getHeight()*3/2);
31 | jbyte* yuvArray = env->GetByteArrayElements(jYuvArray, NULL);
32 | GPUIPBuffer buffer;
33 | buffer.width = graphicBufferEx->getWidth();
34 | buffer.height = graphicBufferEx->getHeight();
35 | buffer.format = graphicBufferEx->getFormat();
36 | buffer.stride = buffer.width;
37 | buffer.length = buffer.stride * buffer.height * 3 / 2;
38 | buffer.pY = yuvArray;
39 | buffer.pU = yuvArray + buffer.stride * buffer.height;
40 | buffer.pV = buffer.pU;
41 |
42 | graphicBufferEx->getBuffer(GPUIPBuffer_NV21_COPY, &buffer);
43 | //LOGI("dump yuv");
44 | //dump("/sdcard/123.yuv", buffer.pY, buffer.length);
45 | env->ReleaseByteArrayElements(jYuvArray, yuvArray, 0);
46 | return jYuvArray;
47 | }
48 |
49 | JNIEXPORT void JNICALL
50 | Java_com_example_copygpu_GLCopyJni_setBuffer(
51 | JNIEnv*env, jclass type, jlong handler, jbyteArray jbuffer)
52 | {
53 | GraphicBufferEx* graphicBufferEx = (GraphicBufferEx*)handler;
54 | jbyte* buffer = env->GetByteArrayElements(jbuffer, NULL);
55 | GPUIPBuffer inputBuffer;
56 | inputBuffer.width = graphicBufferEx->getWidth();
57 | inputBuffer.height = graphicBufferEx->getHeight();
58 | inputBuffer.format = 17; //HAL_PIXEL_FORMAT_YCrCb_420_SP
59 | inputBuffer.stride = inputBuffer.width;
60 | inputBuffer.length = inputBuffer.stride * inputBuffer.height * 3 / 2;
61 | inputBuffer.pY = buffer;
62 | inputBuffer.pU = buffer + inputBuffer.stride * inputBuffer.height;
63 | inputBuffer.pV = inputBuffer.pU;
64 | graphicBufferEx->setBuffer(&inputBuffer);
65 | env->ReleaseByteArrayElements(jbuffer, buffer, 0);
66 | }
--------------------------------------------------------------------------------
/app/src/main/jni/NubiaGLCopy.h:
--------------------------------------------------------------------------------
1 | //
2 | // Author : chenguoting on 2018-8-1 18:38
3 | // Email : chen.guoting@nubia.com
4 | // Company : NUBIA TECHNOLOGY CO., LTD.
5 | //
6 |
7 | #ifndef NEWCAMERA_NUBIAGLCOPY_H
8 | #define NEWCAMERA_NUBIAGLCOPY_H
9 | #include
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | JNIEXPORT jlong JNICALL
15 | Java_com_example_copygpu_GLCopyJni_initHardwareBuffer(
16 | JNIEnv*env, jclass type, jint, jint, jint);
17 |
18 | JNIEXPORT void JNICALL
19 | Java_com_example_copygpu_GLCopyJni_releaseHardwareBuffer(
20 | JNIEnv*env, jclass type, jlong handler);
21 |
22 | JNIEXPORT jbyteArray JNICALL
23 | Java_com_example_copygpu_GLCopyJni_getBuffer(
24 | JNIEnv*env, jclass type, jlong handler);
25 |
26 | JNIEXPORT void JNICALL
27 | Java_com_example_copygpu_GLCopyJni_setBuffer(
28 | JNIEnv*env, jclass type, jlong handler, jbyteArray);
29 |
30 | #ifdef __cplusplus
31 | }
32 | #endif
33 | #endif //NEWCAMERA_NUBIAGLCOPY_H
34 |
--------------------------------------------------------------------------------
/app/src/main/jni/Utils.cpp:
--------------------------------------------------------------------------------
1 | #include "GPUIPCommon.h"
2 | #include
3 | #include
4 | #include "Utils.h"
5 |
6 | void printGLString(const char *name, GLenum s)
7 | {
8 | const char *str = (const char *) glGetString(s);
9 | LOGI("GL %s = %s\n", name, str);
10 | return;
11 | }
12 |
13 | void checkGlError(const char* op)
14 | {
15 | for (GLint error = glGetError(); error; error = glGetError())
16 | {
17 | LOGE("after %s() glError (0x%x)\n", op, error);
18 | }
19 |
20 | return;
21 | }
22 |
23 | void checkEglError(const char* op) {
24 | GLint error = eglGetError();
25 | if(error != EGL_SUCCESS) {
26 | LOGE("after %s() eglError (0x%x)\n", op, error);
27 | }
28 | return;
29 | }
30 |
31 | void printOpenGLInfo()
32 | {
33 | printGLString("Version", GL_VERSION);
34 | printGLString("Vendor", GL_VENDOR);
35 | printGLString("Renderer", GL_RENDERER);
36 | printGLString("Extensions", GL_EXTENSIONS);
37 | return;
38 | }
39 |
40 | float calcAngle(float x, float y)
41 | {
42 | if (x == 0.0f)
43 | {
44 | if (y > 0.0f)
45 | {
46 | return 90.0f;
47 | }
48 | else
49 | {
50 | return 270.0f;
51 | }
52 | }
53 |
54 | float tana = y / x;
55 | float angle = atan(tana) * 180.0f / PI;
56 |
57 | if (x < 0.0f)
58 | {
59 | angle += 180.0f;
60 | }
61 |
62 | if (angle < 0.0f)
63 | {
64 | angle += 360.0f;
65 | }
66 | else if (angle > 360.0f)
67 | {
68 | angle -= 360.0f;
69 | }
70 |
71 | return angle;
72 | }
73 |
74 |
75 | float calcAngleByVec2(float *a, float *b)
76 | {
77 | float aLength = sqrt(a[0] * a[0] + a[1] * a[1]);
78 | float bLength = sqrt(b[0] * b[0] + b[1] * b[1]);
79 |
80 | float cosa = (a[0] * b[0] + a[1] * b[1]) / (aLength * bLength);
81 | return acos(cosa) * 180.0f / PI;
82 | }
83 |
84 | float calcAngleByVec3(float *a, float *b)
85 | {
86 | float aLength = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
87 | float bLength = sqrt(b[0] * b[0] + b[1] * b[1] + b[2] * b[2]);
88 |
89 | float cosa = (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) / (aLength * bLength);
90 | return acos(cosa) * 180.0f / PI;
91 | }
92 |
93 | void depth2Bump(int width, int height,
94 | const uint8_t *pDepthBuffer, uint32_t *pBumpBuffer,
95 | float param1, float param2)
96 | {
97 | int i, j;
98 | int value, valueUp, valueRight;
99 | int vecInt[3];
100 | float vec[3], vecUp[3], vecRight[3];
101 | float module;
102 |
103 | vecUp[0] = 1.0f;
104 | vecUp[1] = 0.0f;
105 | vecRight[0] = 0.0f;
106 | vecRight[1] = 1.0f;
107 |
108 | for (j = 0; j < height; j++)
109 | {
110 | for (i = 0; i < width; i++)
111 | {
112 | value = pDepthBuffer[j * width + i];
113 |
114 | if ((j == 0) || (i == width - 1))
115 | {
116 | pBumpBuffer[j * width + i] = 0x00ff8080 | (value << 24);
117 | continue;
118 | }
119 |
120 | valueUp = pDepthBuffer[(j - 1) * width + i];
121 | valueRight = pDepthBuffer[j * width + (i + 1)];
122 |
123 | vecUp[2] = (valueUp - value) / 255.0f * param1;
124 | vecRight[2] = (valueRight - value) / 255.0f * param2;
125 |
126 | //cross product and normal
127 | vec[0] = vecUp[1] * vecRight[2] - vecRight[1] * vecUp[2];
128 | vec[1] = vecUp[2] * vecRight[0] - vecRight[2] * vecUp[0];
129 | vec[2] = vecUp[0] * vecRight[1] - vecRight[0] * vecUp[1];
130 | module = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
131 | vec[0] /= module;
132 | vec[1] /= module;
133 | vec[2] /= module;
134 |
135 | vecInt[0] = (int)(vec[0] * 128.0f) + 128;
136 | vecInt[1] = (int)(vec[1] * 128.0f) + 128;
137 | vecInt[2] = (int)(vec[2] * 128.0f) + 128;
138 | vecInt[0] = (vecInt[0] > 255) ? 255 : vecInt[0];
139 | vecInt[1] = (vecInt[1] > 255) ? 255 : vecInt[1];
140 | vecInt[2] = (vecInt[2] > 255) ? 255 : vecInt[2];
141 | //ABGR
142 | //pBumpBuffer[j * width + i] = 0xff000000 | (vecInt[2] << 16) | (vecInt[1] << 8) | vecInt[0];
143 | pBumpBuffer[j * width + i] = (value << 24) | (vecInt[2] << 16) | (vecInt[1] << 8) | vecInt[0];
144 | }
145 | }
146 | }
147 |
148 | void dump(const char *pFileName, void *pBufferSrc, int bufferLen)
149 | {
150 | FILE *pFile = fopen(pFileName, "w+");
151 |
152 | if (pFile != NULL)
153 | {
154 | int countWrited = 0;
155 | int countRemind = bufferLen;
156 | uint8_t *pBufferSrcEx = (uint8_t *)pBufferSrc;
157 | uint8_t *pBuffer = pBufferSrcEx;
158 |
159 | do
160 | {
161 | countWrited += fwrite(pBuffer, 1, countRemind, pFile);
162 | pBuffer = pBufferSrcEx + countWrited;
163 | countRemind = bufferLen - countWrited;
164 | } while(countRemind > 0);
165 |
166 | fclose(pFile);
167 | }
168 | else
169 | {
170 | LOGE("dump open file %s error!", pFileName);
171 | }
172 | }
173 |
174 | void unDump(const char *pFileName, void *pBufferSrc, int bufferLen)
175 | {
176 | FILE *pFile = fopen(pFileName, "r");
177 |
178 | if (pFile != NULL)
179 | {
180 | int countRead = 0;
181 | int countRemind = bufferLen;
182 | uint8_t *pBufferSrcEx = (uint8_t *)pBufferSrc;
183 | uint8_t *pBuffer = pBufferSrcEx;
184 |
185 | do
186 | {
187 | countRead += fread(pBuffer, 1, countRemind, pFile);
188 | pBuffer = pBufferSrcEx + countRead;
189 | countRemind = bufferLen - countRead;
190 | } while(countRemind > 0);
191 |
192 | fclose(pFile);
193 | }
194 | else
195 | {
196 | LOGI("unDump open file %s error!", pFileName);
197 | }
198 | }
199 |
200 | void Quaternion::setEulerAngle(const EulerAngle &ea)
201 | {
202 | float cr = cos(ea.roll / 57.3f / 2.0f);
203 | float sr = sin(ea.roll / 57.3f / 2.0f);
204 | float cp = cos(ea.pitch / 57.3f / 2.0f);
205 | float sp = sin(ea.pitch / 57.3f / 2.0f);
206 | float cy = cos(ea.yaw / 57.3f / 2.0f);
207 | float sy = sin(ea.yaw / 57.3f / 2.0f);
208 |
209 | w = cr * cp * cy + sr * sp * sy;
210 | x = cr * sp * cy + sr * cp * sy;
211 | y = cr * cp * sy - sr * sp * cy;
212 | z = sr * cp * cy - cr * sp * sy;
213 | }
214 |
215 | void Quaternion::getEulerAngle(EulerAngle &ea)
216 | {
217 | ea.roll = atan2(2.0f * (w * z + x * y) , 1.0f - 2.0f * (z * z + x * x));
218 | ea.roll *= 57.3f;
219 | ea.pitch = asin(CLAMP(2.0f * (w * x - y * z) , -1.0f , 1.0f));
220 | ea.pitch *= 57.3f;
221 | ea.yaw = atan2(2.0f * (w * y + z * x) , 1.0f - 2.0f * (x * x + y * y));
222 | ea.yaw *= 57.3f;
223 | return;
224 | }
--------------------------------------------------------------------------------
/app/src/main/jni/Utils.h:
--------------------------------------------------------------------------------
1 | #ifndef UTILS_H
2 | #define UTILS_H
3 |
4 | #define CLAMP(x , min , max) ((x) > (max) ? (max) : ((x) < (min) ? (min) : x))
5 |
6 | void printGLString(const char *name, GLenum s);
7 | void checkGlError(const char* op);
8 | void checkEglError(const char* op);
9 | void printOpenGLInfo();
10 | float calcAngle(float x, float y);
11 | float calcAngleByVec2(float *a, float *b);
12 | float calcAngleByVec3(float *a, float *b);
13 | void depth2Bump(int width, int height,
14 | const uint8_t *pDepthBuffer, uint32_t *pBumpBuffer,
15 | float param1, float param2);
16 | void dump(const char *pFileName, void *pBufferSrc, int bufferLen);
17 | void unDump(const char *pFileName, void *pBufferSrc, int bufferLen);
18 |
19 | typedef struct {
20 | float yaw;
21 | float pitch;
22 | float roll;
23 | } EulerAngle;
24 |
25 | class Quaternion
26 | {
27 | public:
28 | float x , y , z , w;
29 |
30 | Quaternion(void) : x(0.0f) , y(0.0f) , z(0.0f) , w(1.0f) {}
31 | ~Quaternion(void) {}
32 | void setEulerAngle(const EulerAngle& ea);
33 | void getEulerAngle(EulerAngle& ea);
34 | };
35 | #endif
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chenguoting/hardwareBuffer/1db3d2ae3267f2250f78ad8beee4cc7e23142c1e/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/raw/texture_2d_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 |
3 | in vec2 vTextureCoord;
4 | uniform sampler2D uTextureSampler;
5 |
6 | out vec4 gl_FragColor;
7 |
8 | void main() {
9 | gl_FragColor = texture(uTextureSampler, vTextureCoord);
10 | }
--------------------------------------------------------------------------------
/app/src/main/res/raw/texture_oes2oes_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | #extension GL_OES_EGL_image_external_essl3 : require
3 | #extension GL_EXT_YUV_target : require
4 |
5 | in vec2 vTextureCoord;
6 | uniform samplerExternalOES uTextureSampler;
7 |
8 | layout(yuv) out vec4 gl_FragColor;
9 |
10 | void main() {
11 | gl_FragColor = texture(uTextureSampler, vTextureCoord);
12 | }
--------------------------------------------------------------------------------
/app/src/main/res/raw/texture_oes_fragment_shader.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | #extension GL_OES_EGL_image_external_essl3 : require
3 |
4 | in vec2 vTextureCoord;
5 | uniform samplerExternalOES uTextureSampler;
6 |
7 | out vec4 gl_FragColor;
8 |
9 | void main() {
10 | gl_FragColor = texture(uTextureSampler, vTextureCoord);
11 | }
--------------------------------------------------------------------------------
/app/src/main/res/raw/texture_vertex_shader.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 |
3 | uniform mat4 uMVPMatrix;
4 | uniform mat4 uSTMatrix;
5 | in vec4 aPosition;
6 | in vec4 aTextureCoord;
7 |
8 | out vec2 vTextureCoord;
9 |
10 | void main() {
11 | gl_Position = uMVPMatrix * aPosition;
12 | vTextureCoord = (uSTMatrix * aTextureCoord).st;
13 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | CopyGPU
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/test/java/com/example/copygpu/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.example.copygpu;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.1'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------