diff options
Diffstat (limited to 'opengl')
90 files changed, 10215 insertions, 597 deletions
diff --git a/opengl/java/android/opengl/ETC1.java b/opengl/java/android/opengl/ETC1.java index f3dac77..fb5f9b4 100644 --- a/opengl/java/android/opengl/ETC1.java +++ b/opengl/java/android/opengl/ETC1.java @@ -1,11 +1,11 @@ /* - * Copyright 2009 Google Inc. + * Copyright (C) 2009 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 + * 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, diff --git a/opengl/java/android/opengl/ETC1Util.java b/opengl/java/android/opengl/ETC1Util.java index dd28d1d..3629d41 100644 --- a/opengl/java/android/opengl/ETC1Util.java +++ b/opengl/java/android/opengl/ETC1Util.java @@ -1,11 +1,11 @@ /* - * Copyright 2009 Google Inc. + * Copyright (C) 2009 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 + * 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, diff --git a/opengl/java/android/opengl/GLES10.java b/opengl/java/android/opengl/GLES10.java index 790acbd..7c0f949 100644 --- a/opengl/java/android/opengl/GLES10.java +++ b/opengl/java/android/opengl/GLES10.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2009, 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. -*/ + * Copyright (C) 2009 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. + */ // This source file is automatically generated diff --git a/opengl/java/android/opengl/GLES10Ext.java b/opengl/java/android/opengl/GLES10Ext.java index 81fc59e..116ab9d 100644 --- a/opengl/java/android/opengl/GLES10Ext.java +++ b/opengl/java/android/opengl/GLES10Ext.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2009, 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. -*/ + * Copyright (C) 2009 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. + */ // This source file is automatically generated diff --git a/opengl/java/android/opengl/GLES11.java b/opengl/java/android/opengl/GLES11.java index 1ca179b..b24c043 100644 --- a/opengl/java/android/opengl/GLES11.java +++ b/opengl/java/android/opengl/GLES11.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2009, 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. -*/ + * Copyright (C) 2009 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. + */ // This source file is automatically generated diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java index 25d5467..a9a7a22 100644 --- a/opengl/java/android/opengl/GLES11Ext.java +++ b/opengl/java/android/opengl/GLES11Ext.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2009, 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. -*/ + * Copyright (C) 2009 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. + */ // This source file is automatically generated diff --git a/opengl/java/android/opengl/GLES20.java b/opengl/java/android/opengl/GLES20.java index 635f811..700164b 100644 --- a/opengl/java/android/opengl/GLES20.java +++ b/opengl/java/android/opengl/GLES20.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2009, 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. -*/ + * Copyright (C) 2009 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. + */ // This source file is automatically generated diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 41207f7..32d1a23 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -155,6 +155,8 @@ import android.view.SurfaceView; * */ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private final static String TAG = "GLSurfaceView"; + private final static boolean LOG_ATTACH_DETACH = false; private final static boolean LOG_THREADS = false; private final static boolean LOG_PAUSE_RESUME = false; private final static boolean LOG_SURFACE = false; @@ -270,6 +272,35 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback } /** + * Control whether the EGL context is preserved when the GLSurfaceView is paused and + * resumed. + * <p> + * If set to true, then the EGL context may be preserved when the GLSurfaceView is paused. + * Whether the EGL context is actually preserved or not depends upon whether the + * Android device that the program is running on can support an arbitrary number of EGL + * contexts or not. Devices that can only support a limited number of EGL contexts must + * release the EGL context in order to allow multiple applications to share the GPU. + * <p> + * If set to false, the EGL context will be released when the GLSurfaceView is paused, + * and recreated when the GLSurfaceView is resumed. + * <p> + * + * The default is false. + * + * @param preserveOnPause preserve the EGL context when paused + */ + public void setPreserveEGLContextOnPause(boolean preserveOnPause) { + mPreserveEGLContextOnPause = preserveOnPause; + } + + /** + * @return true if the EGL context will be preserved when paused + */ + public boolean getPreserveEGLContextOnPause() { + return mPreserveEGLContextOnPause; + } + + /** * Set the renderer associated with this view. Also starts the thread that * will call the renderer, which in turn causes the rendering to start. * <p>This method should be called once and only once in the life-cycle of @@ -306,6 +337,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (mEGLWindowSurfaceFactory == null) { mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory(); } + mRenderer = renderer; mGLThread = new GLThread(renderer); mGLThread.start(); } @@ -525,12 +557,42 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /** * This method is used as part of the View class and is not normally * called or subclassed by clients of GLSurfaceView. + */ + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (LOG_ATTACH_DETACH) { + Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); + } + if (mDetached && (mRenderer != null)) { + int renderMode = RENDERMODE_CONTINUOUSLY; + if (mGLThread != null) { + renderMode = mGLThread.getRenderMode(); + } + mGLThread = new GLThread(mRenderer); + if (renderMode != RENDERMODE_CONTINUOUSLY) { + mGLThread.setRenderMode(renderMode); + } + mGLThread.start(); + } + mDetached = false; + } + + /** + * This method is used as part of the View class and is not normally + * called or subclassed by clients of GLSurfaceView. * Must not be called before a renderer has been set. */ @Override protected void onDetachedFromWindow() { + if (LOG_ATTACH_DETACH) { + Log.d(TAG, "onDetachedFromWindow"); + } + if (mGLThread != null) { + mGLThread.requestExitAndWait(); + } + mDetached = true; super.onDetachedFromWindow(); - mGLThread.requestExitAndWait(); } // ---------------------------------------------------------------------- @@ -1207,7 +1269,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback Log.i("GLThread", "releasing EGL surface because paused tid=" + getId()); } stopEglSurfaceLocked(); - if (sGLThreadManager.shouldReleaseEGLContextWhenPausing()) { + if (!mPreserveEGLContextOnPause || sGLThreadManager.shouldReleaseEGLContextWhenPausing()) { stopEglContextLocked(); if (LOG_SURFACE) { Log.i("GLThread", "releasing EGL context because paused tid=" + getId()); @@ -1672,7 +1734,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback // Release the EGL context when pausing even if // the hardware supports multiple EGL contexts. // Otherwise the device could run out of EGL contexts. - return true; + return mLimitedGLESContexts; } public synchronized boolean shouldTerminateEGLWhenPausing() { @@ -1683,16 +1745,18 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback public synchronized void checkGLDriver(GL10 gl) { if (! mGLESDriverCheckComplete) { checkGLESVersion(); + String renderer = gl.glGetString(GL10.GL_RENDERER); if (mGLESVersion < kGLES_20) { - String renderer = gl.glGetString(GL10.GL_RENDERER); mMultipleGLESContextsAllowed = ! renderer.startsWith(kMSM7K_RENDERER_PREFIX); - if (LOG_SURFACE) { - Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = " - + mMultipleGLESContextsAllowed); - } notifyAll(); } + mLimitedGLESContexts = !mMultipleGLESContextsAllowed || renderer.startsWith(kADRENO); + if (LOG_SURFACE) { + Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = " + + mMultipleGLESContextsAllowed + + " mLimitedGLESContexts = " + mLimitedGLESContexts); + } mGLESDriverCheckComplete = true; } } @@ -1717,9 +1781,11 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private int mGLESVersion; private boolean mGLESDriverCheckComplete; private boolean mMultipleGLESContextsAllowed; + private boolean mLimitedGLESContexts; private static final int kGLES_20 = 0x20000; private static final String kMSM7K_RENDERER_PREFIX = "Q3Dimension MSM7500 "; + private static final String kADRENO = "Adreno"; private GLThread mEglOwner; } @@ -1727,10 +1793,13 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private boolean mSizeChanged = true; private GLThread mGLThread; + private Renderer mRenderer; + private boolean mDetached; private EGLConfigChooser mEGLConfigChooser; private EGLContextFactory mEGLContextFactory; private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory; private GLWrapper mGLWrapper; private int mDebugFlags; private int mEGLContextClientVersion; + private boolean mPreserveEGLContextOnPause; } diff --git a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java index b03392e..c2f4400 100644 --- a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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.google.android.gles_jni; diff --git a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java index f10c02f..9cf5de7 100644 --- a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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.google.android.gles_jni; diff --git a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java index 6321632..cb94888 100644 --- a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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.google.android.gles_jni; diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java index 3e06ded..8a7124d 100644 --- a/opengl/java/com/google/android/gles_jni/EGLImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java @@ -1,19 +1,18 @@ /* -** -** Copyright 2006, 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. -*/ + * Copyright (C) 2006 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.google.android.gles_jni; diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java index 66cc200..f6b90ab 100644 --- a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java +++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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.google.android.gles_jni; diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java index 090c0cb..50f6760 100644 --- a/opengl/java/com/google/android/gles_jni/GLImpl.java +++ b/opengl/java/com/google/android/gles_jni/GLImpl.java @@ -1,19 +1,18 @@ -/* //device/java/android/com/google/android/gles_jni/GLImpl.java -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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. + */ // This source file is automatically generated diff --git a/opengl/java/javax/microedition/khronos/egl/EGL.java b/opengl/java/javax/microedition/khronos/egl/EGL.java index b743968..18f8ae6 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGL.java +++ b/opengl/java/javax/microedition/khronos/egl/EGL.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.egl; diff --git a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java index a1e496c..c8a9ba2 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java +++ b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.egl; diff --git a/opengl/java/javax/microedition/khronos/egl/EGLContext.java b/opengl/java/javax/microedition/khronos/egl/EGLContext.java index fc94492..f8d745d 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGLContext.java +++ b/opengl/java/javax/microedition/khronos/egl/EGLContext.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.egl; diff --git a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java index cd8a755..5368b4b 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java +++ b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.egl; diff --git a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java index 5349bc1..e1d08d3 100644 --- a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java +++ b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java @@ -1,19 +1,18 @@ -/* -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.egl; diff --git a/opengl/java/javax/microedition/khronos/opengles/GL.java b/opengl/java/javax/microedition/khronos/opengles/GL.java index 3b78f3d..d5b60c6 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL.java -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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 javax.microedition.khronos.opengles; diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10.java b/opengl/java/javax/microedition/khronos/opengles/GL10.java index 4fcfb52..f48ecde 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL10.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL10.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL10.java -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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. + */ // This source file is automatically generated diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java index 562b20a..f3252ab 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL10Ext.java -** -** Copyright 2007, 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. -*/ +/* + * Copyright (C) 2007 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. + */ // This source file is automatically generated diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11.java b/opengl/java/javax/microedition/khronos/opengles/GL11.java index 3ba110c..943a5be 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL11.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL11.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL11.java -** -** Copyright 2006, 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. -*/ +/* + * Copyright (C) 2006 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. + */ // This source file is automatically generated diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java index 459a1ab..842db7a 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL11Ext.java -** -** Copyright 2007, 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. -*/ +/* + * Copyright (C) 2007 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. + */ // This source file is automatically generated diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java index 933c91e..97d5fd8 100644 --- a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java +++ b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java @@ -1,19 +1,18 @@ -/* //device/java/android/javax/microedition/khronos/opengles/GL11ExtensionPack.java -** -** Copyright 2007, 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. -*/ +/* + * Copyright (C) 2007 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. + */ // This source file is automatically generated diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 5c09dcc..7ac6f92 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -40,7 +40,6 @@ #include <pixelflinger/pixelflinger.h> #include <private/ui/android_natives_priv.h> -#include <private/ui/sw_gralloc_handle.h> #include <hardware/copybit.h> @@ -446,15 +445,10 @@ status_t egl_window_surface_v2_t::lock( android_native_buffer_t* buf, int usage, void** vaddr) { int err; - if (sw_gralloc_handle_t::validate(buf->handle) < 0) { - err = module->lock(module, buf->handle, - usage, 0, 0, buf->width, buf->height, vaddr); - } else { - sw_gralloc_handle_t const* hnd = - reinterpret_cast<sw_gralloc_handle_t const*>(buf->handle); - *vaddr = (void*)hnd->base; - err = NO_ERROR; - } + + err = module->lock(module, buf->handle, + usage, 0, 0, buf->width, buf->height, vaddr); + return err; } @@ -462,9 +456,9 @@ status_t egl_window_surface_v2_t::unlock(android_native_buffer_t* buf) { if (!buf) return BAD_VALUE; int err = NO_ERROR; - if (sw_gralloc_handle_t::validate(buf->handle) < 0) { - err = module->unlock(module, buf->handle); - } + + err = module->unlock(module, buf->handle); + return err; } @@ -546,7 +540,9 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() if (!dirtyRegion.isEmpty()) { dirtyRegion.andSelf(Rect(buffer->width, buffer->height)); if (previousBuffer) { - const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); + // This was const Region copyBack, but that causes an + // internal compile error on simulator builds + /*const*/ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); if (!copyBack.isEmpty()) { void* prevBits; if (lock(previousBuffer, @@ -1980,7 +1976,7 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) if (egl_display_t::is_valid(dpy) == EGL_FALSE) return setError(EGL_BAD_DISPLAY, EGL_FALSE); // TODO: eglSwapInterval() - return setError(EGL_BAD_PARAMETER, EGL_FALSE); + return EGL_TRUE; } // ---------------------------------------------------------------------------- diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index ae924cd..c8041fc 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -8,6 +8,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ EGL/egl.cpp \ + EGL/trace.cpp \ EGL/getProcAddress.cpp.arm \ EGL/hooks.cpp \ EGL/Loader.cpp \ @@ -33,6 +34,7 @@ endif LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden +LOCAL_CFLAGS += -DEGL_TRACE=1 ifeq ($(TARGET_BOARD_PLATFORM),msm7k) LOCAL_CFLAGS += -DADRENO130=1 diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index ebe2193..8977fbf 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -61,6 +61,10 @@ static char const * const gExtensionString = "EGL_KHR_image " "EGL_KHR_image_base " "EGL_KHR_image_pixmap " + "EGL_KHR_gl_texture_2D_image " + "EGL_KHR_gl_texture_cubemap_image " + "EGL_KHR_gl_renderbuffer_image " + "EGL_KHR_fence_sync " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " ; @@ -246,9 +250,23 @@ struct egl_image_t : public egl_object_t EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS]; }; +struct egl_sync_t : public egl_object_t +{ + typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref; + + egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) + : dpy(dpy), context(context), sync(sync) + { + } + EGLDisplay dpy; + EGLContext context; + EGLSyncKHR sync; +}; + typedef egl_surface_t::Ref SurfaceRef; typedef egl_context_t::Ref ContextRef; typedef egl_image_t::Ref ImageRef; +typedef egl_sync_t::Ref SyncRef; struct tls_t { @@ -272,6 +290,58 @@ EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; EGLAPI gl_hooks_t gHooksNoContext; EGLAPI pthread_key_t gGLWrapperKey = -1; +#if EGL_TRACE + +EGLAPI pthread_key_t gGLTraceKey = -1; + +// ---------------------------------------------------------------------------- + +static int gEGLTraceLevel; +static int gEGLApplicationTraceLevel; +extern EGLAPI gl_hooks_t gHooksTrace; + +static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { + pthread_setspecific(gGLTraceKey, value); +} + +gl_hooks_t const* getGLTraceThreadSpecific() { + return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey)); +} + +static void initEglTraceLevel() { + char value[PROPERTY_VALUE_MAX]; + property_get("debug.egl.trace", value, "0"); + int propertyLevel = atoi(value); + int applicationLevel = gEGLApplicationTraceLevel; + gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; +} + +static void setGLHooksThreadSpecific(gl_hooks_t const *value) { + if (gEGLTraceLevel > 0) { + setGlTraceThreadSpecific(value); + setGlThreadSpecific(&gHooksTrace); + } else { + setGlThreadSpecific(value); + } +} + +/* + * Global entry point to allow applications to modify their own trace level. + * The effective trace level is the max of this level and the value of debug.egl.trace. + */ +extern "C" +void setGLTraceLevel(int level) { + gEGLApplicationTraceLevel = level; +} + +#else + +static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) { + setGlThreadSpecific(value); +} + +#endif + // ---------------------------------------------------------------------------- static __attribute__((noinline)) @@ -318,6 +388,13 @@ static tls_t* getTLS() return tls; } +static inline void clearError() { + if (gEGLThreadLocalStorageKey != -1) { + tls_t* tls = getTLS(); + tls->error = EGL_SUCCESS; + } +} + template<typename T> static __attribute__((noinline)) T setErrorEtc(const char* caller, int line, EGLint error, T returnValue) { @@ -410,10 +487,6 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, { "eglSetSwapRectangleANDROID", (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, - { "glEGLImageTargetTexture2DOES", - (__eglMustCastToProperFunctionPointerType)NULL }, - { "glEGLImageTargetRenderbufferStorageOES", - (__eglMustCastToProperFunctionPointerType)NULL }, }; extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS]; @@ -450,13 +523,17 @@ static void early_egl_init(void) #if !USE_FAST_TLS_KEY pthread_key_create(&gGLWrapperKey, NULL); #endif +#if EGL_TRACE + pthread_key_create(&gGLTraceKey, NULL); + initEglTraceLevel(); +#endif uint32_t addr = (uint32_t)((void*)gl_no_context); android_memset32( (uint32_t*)(void*)&gHooksNoContext, addr, sizeof(gHooksNoContext)); - setGlThreadSpecific(&gHooksNoContext); + setGLHooksThreadSpecific(&gHooksNoContext); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; @@ -490,6 +567,11 @@ egl_image_t* get_image(EGLImageKHR image) { return egl_to_native_cast<egl_image_t>(image); } +static inline +egl_sync_t* get_sync(EGLSyncKHR sync) { + return egl_to_native_cast<egl_sync_t>(sync); +} + static egl_connection_t* validate_display_config( EGLDisplay dpy, EGLConfig config, egl_display_t const*& dp) @@ -633,6 +715,8 @@ using namespace android; EGLDisplay eglGetDisplay(NativeDisplayType display) { + clearError(); + uint32_t index = uint32_t(display); if (index >= NUM_DISPLAYS) { return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY); @@ -652,6 +736,8 @@ EGLDisplay eglGetDisplay(NativeDisplayType display) EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { + clearError(); + egl_display_t * const dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -663,9 +749,17 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) dp->refs++; return EGL_TRUE; } - - setGlThreadSpecific(&gHooksNoContext); - + +#if EGL_TRACE + + // Called both at early_init time and at this time. (Early_init is pre-zygote, so + // the information from that call may be stale.) + initEglTraceLevel(); + +#endif + + setGLHooksThreadSpecific(&gHooksNoContext); + // initialize each EGL and // build our own extension string first, based on the extension we know // and the extension supported by our client implementation @@ -775,6 +869,8 @@ EGLBoolean eglTerminate(EGLDisplay dpy) // after eglTerminate() has been called. eglTerminate() only // terminates an EGLDisplay, not a EGL itself. + clearError(); + egl_display_t* const dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -814,7 +910,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy) dp->refs--; dp->numTotalConfigs = 0; delete [] dp->configs; - clearTLS(); + return res; } @@ -826,6 +922,8 @@ EGLBoolean eglGetConfigs( EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { + clearError(); + egl_display_t const * const dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -850,6 +948,8 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { + clearError(); + egl_display_t const * const dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -963,6 +1063,8 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (!cnx) return EGL_FALSE; @@ -984,6 +1086,8 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { @@ -1014,6 +1118,8 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { @@ -1032,6 +1138,8 @@ EGLSurface eglCreatePixmapSurface( EGLDisplay dpy, EGLConfig config, EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { @@ -1049,6 +1157,8 @@ EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config, EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1071,6 +1181,8 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1098,6 +1210,8 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (cnx) { @@ -1135,6 +1249,8 @@ EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { + clearError(); + ContextRef _c(ctx); if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); @@ -1150,9 +1266,32 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return result; } +static void loseCurrent(egl_context_t * cur_c) +{ + if (cur_c) { + egl_surface_t * cur_r = get_surface(cur_c->read); + egl_surface_t * cur_d = get_surface(cur_c->draw); + + // by construction, these are either 0 or valid (possibly terminated) + // it should be impossible for these to be invalid + ContextRef _cur_c(cur_c); + SurfaceRef _cur_r(cur_r); + SurfaceRef _cur_d(cur_d); + + cur_c->read = NULL; + cur_c->draw = NULL; + + _cur_c.release(); + _cur_r.release(); + _cur_d.release(); + } +} + EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { + clearError(); + // get a reference to the object passed in ContextRef _c(ctx); SurfaceRef _d(draw); @@ -1178,13 +1317,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // these are the current objects structs egl_context_t * cur_c = get_context(getContext()); - egl_surface_t * cur_r = NULL; - egl_surface_t * cur_d = NULL; if (ctx != EGL_NO_CONTEXT) { c = get_context(ctx); - cur_r = get_surface(c->read); - cur_d = get_surface(c->draw); impl_ctx = c->context; } else { // no context given, use the implementation of the current context @@ -1230,30 +1365,21 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, } if (result == EGL_TRUE) { - // by construction, these are either 0 or valid (possibly terminated) - // it should be impossible for these to be invalid - ContextRef _cur_c(cur_c); - SurfaceRef _cur_r(cur_r); - SurfaceRef _cur_d(cur_d); - // cur_c has to be valid here (but could be terminated) + loseCurrent(cur_c); + if (ctx != EGL_NO_CONTEXT) { - setGlThreadSpecific(c->cnx->hooks[c->version]); + setGLHooksThreadSpecific(c->cnx->hooks[c->version]); setContext(ctx); _c.acquire(); + _r.acquire(); + _d.acquire(); + c->read = read; + c->draw = draw; } else { - setGlThreadSpecific(&gHooksNoContext); + setGLHooksThreadSpecific(&gHooksNoContext); setContext(EGL_NO_CONTEXT); } - _cur_c.release(); - - _r.acquire(); - _cur_r.release(); - if (c) c->read = read; - - _d.acquire(); - _cur_d.release(); - if (c) c->draw = draw; } return result; } @@ -1262,6 +1388,8 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { + clearError(); + ContextRef _c(ctx); if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); @@ -1288,6 +1416,8 @@ EGLContext eglGetCurrentContext(void) // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would correctly return EGL_NO_CONTEXT. + clearError(); + EGLContext ctx = getContext(); return ctx; } @@ -1297,6 +1427,8 @@ EGLSurface eglGetCurrentSurface(EGLint readdraw) // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would correctly return EGL_NO_SURFACE. + clearError(); + EGLContext ctx = getContext(); if (ctx) { egl_context_t const * const c = get_context(ctx); @@ -1315,6 +1447,8 @@ EGLDisplay eglGetCurrentDisplay(void) // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would correctly return EGL_NO_DISPLAY. + clearError(); + EGLContext ctx = getContext(); if (ctx) { egl_context_t const * const c = get_context(ctx); @@ -1329,6 +1463,8 @@ EGLBoolean eglWaitGL(void) // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would return GL_TRUE, which isn't wrong. + clearError(); + EGLBoolean res = EGL_TRUE; EGLContext ctx = getContext(); if (ctx) { @@ -1348,7 +1484,9 @@ EGLBoolean eglWaitNative(EGLint engine) { // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would return GL_TRUE, which isn't wrong. - + + clearError(); + EGLBoolean res = EGL_TRUE; EGLContext ctx = getContext(); if (ctx) { @@ -1382,12 +1520,37 @@ EGLint eglGetError(void) return result; } +// Note: Similar implementations of these functions also exist in +// gl2.cpp and gl.cpp, and are used by applications that call the +// exported entry points directly. +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image); +typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); + +static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_impl = NULL; +static PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES_impl = NULL; + +static void glEGLImageTargetTexture2DOES_wrapper(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + glEGLImageTargetTexture2DOES_impl(target, implImage); +} + +static void glEGLImageTargetRenderbufferStorageOES_wrapper(GLenum target, GLeglImageOES image) +{ + GLeglImageOES implImage = + (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image); + glEGLImageTargetRenderbufferStorageOES_impl(target, implImage); +} + __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) { // eglGetProcAddress() could be the very first function called // in which case we must make sure we've initialized ourselves, this // happens the first time egl_get_display() is called. + clearError(); + if (egl_init_drivers() == EGL_FALSE) { setError(EGL_BAD_PARAMETER, NULL); return NULL; @@ -1434,11 +1597,24 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) // Extensions are independent of the bound context cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] = cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] = +#if EGL_TRACE + gHooksTrace.ext.extensions[slot] = +#endif cnx->egl.eglGetProcAddress(procname); } } if (found) { addr = gExtensionForwarders[slot]; + + if (!strcmp(procname, "glEGLImageTargetTexture2DOES")) { + glEGLImageTargetTexture2DOES_impl = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)addr; + addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES_wrapper; + } + if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES")) { + glEGLImageTargetRenderbufferStorageOES_impl = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)addr; + addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES_wrapper; + } + gGLExtentionMap.add(name, addr); gGLExtentionSlot++; } @@ -1450,6 +1626,8 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) { + clearError(); + SurfaceRef _s(draw); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1463,6 +1641,8 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw) EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, NativePixmapType target) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1476,6 +1656,8 @@ EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface, const char* eglQueryString(EGLDisplay dpy, EGLint name) { + clearError(); + egl_display_t const * const dp = get_display(dpy); switch (name) { case EGL_VENDOR: @@ -1498,6 +1680,8 @@ const char* eglQueryString(EGLDisplay dpy, EGLint name) EGLBoolean eglSurfaceAttrib( EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1515,6 +1699,8 @@ EGLBoolean eglSurfaceAttrib( EGLBoolean eglBindTexImage( EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1532,6 +1718,8 @@ EGLBoolean eglBindTexImage( EGLBoolean eglReleaseTexImage( EGLDisplay dpy, EGLSurface surface, EGLint buffer) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1548,6 +1736,8 @@ EGLBoolean eglReleaseTexImage( EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { + clearError(); + egl_display_t * const dp = get_display(dpy); if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -1573,6 +1763,8 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) EGLBoolean eglWaitClient(void) { + clearError(); + // could be called before eglInitialize(), but we wouldn't have a context // then, and this function would return GL_TRUE, which isn't wrong. EGLBoolean res = EGL_TRUE; @@ -1596,6 +1788,8 @@ EGLBoolean eglWaitClient(void) EGLBoolean eglBindAPI(EGLenum api) { + clearError(); + if (egl_init_drivers() == EGL_FALSE) { return setError(EGL_BAD_PARAMETER, EGL_FALSE); } @@ -1617,6 +1811,8 @@ EGLBoolean eglBindAPI(EGLenum api) EGLenum eglQueryAPI(void) { + clearError(); + if (egl_init_drivers() == EGL_FALSE) { return setError(EGL_BAD_PARAMETER, EGL_FALSE); } @@ -1637,6 +1833,11 @@ EGLenum eglQueryAPI(void) EGLBoolean eglReleaseThread(void) { + clearError(); + + // If there is context bound to the thread, release it + loseCurrent(get_context(getContext())); + for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) { egl_connection_t* const cnx = &gEGLImpl[i]; if (cnx->dso) { @@ -1653,6 +1854,8 @@ EGLSurface eglCreatePbufferFromClientBuffer( EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { + clearError(); + egl_display_t const* dp = 0; egl_connection_t* cnx = validate_display_config(dpy, config, dp); if (!cnx) return EGL_FALSE; @@ -1672,6 +1875,8 @@ EGLSurface eglCreatePbufferFromClientBuffer( EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1690,6 +1895,8 @@ EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) { + clearError(); + SurfaceRef _s(surface); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); @@ -1709,6 +1916,8 @@ EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface) EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) { + clearError(); + if (ctx != EGL_NO_CONTEXT) { ContextRef _c(ctx); if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); @@ -1780,6 +1989,8 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) { + clearError(); + egl_display_t const * const dp = get_display(dpy); if (dp == 0) { return setError(EGL_BAD_DISPLAY, EGL_FALSE); @@ -1811,6 +2022,119 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) return EGL_TRUE; } +// ---------------------------------------------------------------------------- +// EGL_EGLEXT_VERSION 5 +// ---------------------------------------------------------------------------- + + +EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + clearError(); + + EGLContext ctx = eglGetCurrentContext(); + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR); + if (!validate_display_context(dpy, ctx)) + return EGL_NO_SYNC_KHR; + egl_display_t const * const dp = get_display(dpy); + egl_context_t * const c = get_context(ctx); + EGLSyncKHR result = EGL_NO_SYNC_KHR; + if (c->cnx->egl.eglCreateSyncKHR) { + EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR( + dp->disp[c->impl].dpy, type, attrib_list); + if (sync == EGL_NO_SYNC_KHR) + return sync; + result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync); + } + return (EGLSyncKHR)result; +} + +EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + clearError(); + + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglDestroySyncKHR) { + return c->cnx->egl.eglDestroySyncKHR( + dp->disp[c->impl].dpy, syncObject->sync); + } + + return EGL_FALSE; +} + +EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + clearError(); + + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglClientWaitSyncKHR) { + return c->cnx->egl.eglClientWaitSyncKHR( + dp->disp[c->impl].dpy, syncObject->sync, flags, timeout); + } + + return EGL_FALSE; +} + +EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + clearError(); + + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglGetSyncAttribKHR) { + return c->cnx->egl.eglGetSyncAttribKHR( + dp->disp[c->impl].dpy, syncObject->sync, attribute, value); + } + + return EGL_FALSE; +} // ---------------------------------------------------------------------------- // ANDROID extensions @@ -1819,6 +2143,8 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height) { + clearError(); + SurfaceRef _s(draw); if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE); diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in index 5d89287..63c3c19 100644 --- a/opengl/libs/EGL/egl_entries.in +++ b/opengl/libs/EGL/egl_entries.in @@ -51,6 +51,13 @@ EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface) EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *) EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR) +/* EGL_EGLEXT_VERSION 5 */ + +EGL_ENTRY(EGLSyncKHR, eglCreateSyncKHR, EGLDisplay, EGLenum, const EGLint *) +EGL_ENTRY(EGLBoolean, eglDestroySyncKHR, EGLDisplay, EGLSyncKHR) +EGL_ENTRY(EGLint, eglClientWaitSyncKHR, EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR) +EGL_ENTRY(EGLBoolean, eglGetSyncAttribKHR, EGLDisplay, EGLSyncKHR, EGLint, EGLint *) + /* ANDROID extensions */ EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp new file mode 100644 index 0000000..d3e96ba --- /dev/null +++ b/opengl/libs/EGL/trace.cpp @@ -0,0 +1,355 @@ +/* + ** Copyright 2010, 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. + */ + +#if EGL_TRACE + +#include <stdarg.h> +#include <stdlib.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <cutils/log.h> + +#include "hooks.h" + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +struct GLenumString { + GLenum e; + const char* s; +}; + +#undef GL_ENUM +#define GL_ENUM(VAL,NAME) {VAL, #NAME}, + +static GLenumString g_enumnames[] = { +#include "enums.in" +}; +#undef GL_ENUM + +static int compareGLEnum(const void* a, const void* b) { + return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e; +} + +static const char* GLEnumToString(GLenum e) { + GLenumString key = {e, ""}; + const GLenumString* result = (const GLenumString*) bsearch( + &key, g_enumnames, + sizeof(g_enumnames) / sizeof(g_enumnames[0]), + sizeof(g_enumnames[0]), compareGLEnum); + if (result) { + return result->s; + } + return NULL; +} + +static const char* GLbooleanToString(GLboolean arg) { + return arg ? "GL_TRUE" : "GL_FALSE"; +} + +static GLenumString g_bitfieldNames[] = { + {0x00004000, "GL_COLOR_BUFFER_BIT"}, + {0x00000400, "GL_STENCIL_BUFFER_BIT"}, + {0x00000100, "GL_DEPTH_BUFFER_BIT"} +}; + +class StringBuilder { + static const int lineSize = 500; + char line[lineSize]; + int line_index; +public: + StringBuilder() { + line_index = 0; + line[0] = '\0'; + } + void append(const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + line_index += vsnprintf(line + line_index, lineSize-line_index, fmt, argp); + va_end(argp); + } + const char* getString() { + line_index = 0; + line[lineSize-1] = '\0'; + return line; + } +}; + + +static void TraceGLShaderSource(GLuint shader, GLsizei count, + const GLchar** string, const GLint* length) { + LOGD("const char* shaderSrc[] = {"); + for (GLsizei i = 0; i < count; i++) { + const char* comma = i < count-1 ? "," : ""; + const GLchar* s = string[i]; + if (length) { + GLint len = length[i]; + LOGD(" \"%*s\"%s", len, s, comma); + } else { + LOGD(" \"%s\"%s", s, comma); + } + } + LOGD("};"); + if (length) { + LOGD("const GLint* shaderLength[] = {"); + for (GLsizei i = 0; i < count; i++) { + const char* comma = i < count-1 ? "," : ""; + GLint len = length[i]; + LOGD(" \"%d\"%s", len, comma); + } + LOGD("};"); + LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);", + shader, count); + } else { + LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);", + shader, count); + } +} + +static void TraceValue(int elementCount, char type, + GLsizei chunkCount, GLsizei chunkSize, const void* value) { + StringBuilder stringBuilder; + GLsizei count = chunkCount * chunkSize; + bool isFloat = type == 'f'; + const char* typeString = isFloat ? "GLfloat" : "GLint"; + LOGD("const %s value[] = {", typeString); + for (GLsizei i = 0; i < count; i++) { + StringBuilder builder; + builder.append(" "); + for (int e = 0; e < elementCount; e++) { + const char* comma = ", "; + if (e == elementCount-1) { + if (i == count - 1) { + comma = ""; + } else { + comma = ","; + } + } + if (isFloat) { + builder.append("%g%s", * (GLfloat*) value, comma); + value = (void*) (((GLfloat*) value) + 1); + } else { + builder.append("%d%s", * (GLint*) value, comma); + value = (void*) (((GLint*) value) + 1); + } + } + LOGD("%s", builder.getString()); + if (chunkSize > 1 && i < count-1 + && (i % chunkSize) == (chunkSize-1)) { + LOGD("%s", ""); // Print a blank line. + } + } + LOGD("};"); +} + +static void TraceUniformv(int elementCount, char type, + GLuint location, GLsizei count, const void* value) { + TraceValue(elementCount, type, count, 1, value); + LOGD("glUniform%d%c(%u, %u, value);", elementCount, type, location, count); +} + +static void TraceUniformMatrix(int matrixSideLength, + GLuint location, GLsizei count, GLboolean transpose, const void* value) { + TraceValue(matrixSideLength, 'f', count, matrixSideLength, value); + LOGD("glUniformMatrix%dfv(%u, %u, %s, value);", matrixSideLength, location, count, + GLbooleanToString(transpose)); +} + +static void TraceGL(const char* name, int numArgs, ...) { + va_list argp; + va_start(argp, numArgs); + int nameLen = strlen(name); + + // glShaderSource + if (nameLen == 14 && strcmp(name, "glShaderSource") == 0) { + va_arg(argp, const char*); + GLuint shader = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + const GLchar** string = (const GLchar**) va_arg(argp, void*); + va_arg(argp, const char*); + const GLint* length = (const GLint*) va_arg(argp, void*); + va_end(argp); + TraceGLShaderSource(shader, count, string, length); + return; + } + + // glUniformXXv + + if (nameLen == 12 && strncmp(name, "glUniform", 9) == 0 && name[11] == 'v') { + int elementCount = name[9] - '0'; // 1..4 + char type = name[10]; // 'f' or 'i' + va_arg(argp, const char*); + GLuint location = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + const void* value = (const void*) va_arg(argp, void*); + va_end(argp); + TraceUniformv(elementCount, type, location, count, value); + return; + } + + // glUniformMatrixXfv + + if (nameLen == 18 && strncmp(name, "glUniformMatrix", 15) == 0 + && name[16] == 'f' && name[17] == 'v') { + int matrixSideLength = name[15] - '0'; // 2..4 + va_arg(argp, const char*); + GLuint location = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + GLboolean transpose = (GLboolean) va_arg(argp, int); + va_arg(argp, const char*); + const void* value = (const void*) va_arg(argp, void*); + va_end(argp); + TraceUniformMatrix(matrixSideLength, location, count, transpose, value); + return; + } + + StringBuilder builder; + builder.append("%s(", name); + for (int i = 0; i < numArgs; i++) { + if (i > 0) { + builder.append(", "); + } + const char* type = va_arg(argp, const char*); + bool isPtr = type[strlen(type)-1] == '*' + || strcmp(type, "GLeglImageOES") == 0; + if (isPtr) { + const void* arg = va_arg(argp, const void*); + builder.append("(%s) 0x%08x", type, (size_t) arg); + } else if (strcmp(type, "GLbitfield") == 0) { + size_t arg = va_arg(argp, size_t); + bool first = true; + for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) { + const GLenumString* b = &g_bitfieldNames[i]; + if (b->e & arg) { + if (first) { + first = false; + } else { + builder.append(" | "); + } + builder.append("%s", b->s); + arg &= ~b->e; + } + } + if (first || arg != 0) { + if (!first) { + builder.append(" | "); + } + builder.append("0x%08x", arg); + } + } else if (strcmp(type, "GLboolean") == 0) { + GLboolean arg = va_arg(argp, int); + builder.append("%s", GLbooleanToString(arg)); + } else if (strcmp(type, "GLclampf") == 0) { + double arg = va_arg(argp, double); + builder.append("%g", arg); + } else if (strcmp(type, "GLenum") == 0) { + GLenum arg = va_arg(argp, int); + const char* s = GLEnumToString(arg); + if (s) { + builder.append("%s", s); + } else { + builder.append("0x%x", arg); + } + } else if (strcmp(type, "GLfixed") == 0) { + int arg = va_arg(argp, int); + builder.append("0x%08x", arg); + } else if (strcmp(type, "GLfloat") == 0) { + double arg = va_arg(argp, double); + builder.append("%g", arg); + } else if (strcmp(type, "GLint") == 0) { + int arg = va_arg(argp, int); + const char* s = NULL; + if (strcmp(name, "glTexParameteri") == 0) { + s = GLEnumToString(arg); + } + if (s) { + builder.append("%s", s); + } else { + builder.append("%d", arg); + } + } else if (strcmp(type, "GLintptr") == 0) { + int arg = va_arg(argp, unsigned int); + builder.append("%u", arg); + } else if (strcmp(type, "GLsizei") == 0) { + int arg = va_arg(argp, size_t); + builder.append("%u", arg); + } else if (strcmp(type, "GLsizeiptr") == 0) { + int arg = va_arg(argp, size_t); + builder.append("%u", arg); + } else if (strcmp(type, "GLuint") == 0) { + int arg = va_arg(argp, unsigned int); + builder.append("%u", arg); + } else { + builder.append("/* ??? %s */", type); + break; + } + } + builder.append(");"); + LOGD("%s", builder.getString()); + va_end(argp); +} + +#undef TRACE_GL_VOID +#undef TRACE_GL + +#define TRACE_GL_VOID(_api, _args, _argList, ...) \ +static void Tracing_ ## _api _args { \ + TraceGL(#_api, __VA_ARGS__); \ + gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ + _c->_api _argList; \ +} + +#define TRACE_GL(_type, _api, _args, _argList, ...) \ +static _type Tracing_ ## _api _args { \ + TraceGL(#_api, __VA_ARGS__); \ + gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ + return _c->_api _argList; \ +} + +extern "C" { +#include "../trace.in" +} +#undef TRACE_GL_VOID +#undef TRACE_GL + +#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api, + +EGLAPI gl_hooks_t gHooksTrace = { + { + #include "entries.in" + }, + { + {0} + } +}; +#undef GL_ENTRY + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + +#endif // EGL_TRACE diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index 18dd483..fee4609 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -39,6 +39,8 @@ using namespace android; #undef CALL_GL_API #undef CALL_GL_API_RETURN +#define DEBUG_CALL_GL_API 0 + #if USE_FAST_TLS_KEY #ifdef HAVE_ARM_TLS_REGISTER @@ -74,10 +76,24 @@ using namespace android; #define API_ENTRY(_api) _api +#if DEBUG_CALL_GL_API + + #define CALL_GL_API(_api, ...) \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ + _c->_api(__VA_ARGS__); \ + GLenum status = GL_NO_ERROR; \ + while ((status = glGetError()) != GL_NO_ERROR) { \ + LOGD("[" #_api "] 0x%x", status); \ + } + +#else + #define CALL_GL_API(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - _c->_api(__VA_ARGS__) - + _c->_api(__VA_ARGS__); + +#endif + #define CALL_GL_API_RETURN(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ return _c->_api(__VA_ARGS__) diff --git a/opengl/libs/enums.in b/opengl/libs/enums.in new file mode 100644 index 0000000..f9752c2 --- /dev/null +++ b/opengl/libs/enums.in @@ -0,0 +1,594 @@ +GL_ENUM(0x0000,GL_POINTS) +GL_ENUM(0x0001,GL_LINES) +GL_ENUM(0x0002,GL_LINE_LOOP) +GL_ENUM(0x0003,GL_LINE_STRIP) +GL_ENUM(0x0004,GL_TRIANGLES) +GL_ENUM(0x0005,GL_TRIANGLE_STRIP) +GL_ENUM(0x0006,GL_TRIANGLE_FAN) +GL_ENUM(0x0104,GL_ADD) +GL_ENUM(0x0200,GL_NEVER) +GL_ENUM(0x0201,GL_LESS) +GL_ENUM(0x0202,GL_EQUAL) +GL_ENUM(0x0203,GL_LEQUAL) +GL_ENUM(0x0204,GL_GREATER) +GL_ENUM(0x0205,GL_NOTEQUAL) +GL_ENUM(0x0206,GL_GEQUAL) +GL_ENUM(0x0207,GL_ALWAYS) +GL_ENUM(0x0300,GL_SRC_COLOR) +GL_ENUM(0x0301,GL_ONE_MINUS_SRC_COLOR) +GL_ENUM(0x0302,GL_SRC_ALPHA) +GL_ENUM(0x0303,GL_ONE_MINUS_SRC_ALPHA) +GL_ENUM(0x0304,GL_DST_ALPHA) +GL_ENUM(0x0305,GL_ONE_MINUS_DST_ALPHA) +GL_ENUM(0x0306,GL_DST_COLOR) +GL_ENUM(0x0307,GL_ONE_MINUS_DST_COLOR) +GL_ENUM(0x0308,GL_SRC_ALPHA_SATURATE) +GL_ENUM(0x0404,GL_FRONT) +GL_ENUM(0x0405,GL_BACK) +GL_ENUM(0x0408,GL_FRONT_AND_BACK) +GL_ENUM(0x0500,GL_INVALID_ENUM) +GL_ENUM(0x0501,GL_INVALID_VALUE) +GL_ENUM(0x0502,GL_INVALID_OPERATION) +GL_ENUM(0x0503,GL_STACK_OVERFLOW) +GL_ENUM(0x0504,GL_STACK_UNDERFLOW) +GL_ENUM(0x0505,GL_OUT_OF_MEMORY) +GL_ENUM(0x0506,GL_INVALID_FRAMEBUFFER_OPERATION_OES) +GL_ENUM(0x0800,GL_EXP) +GL_ENUM(0x0801,GL_EXP2) +GL_ENUM(0x0900,GL_CW) +GL_ENUM(0x0901,GL_CCW) +GL_ENUM(0x0B00,GL_CURRENT_COLOR) +GL_ENUM(0x0B02,GL_CURRENT_NORMAL) +GL_ENUM(0x0B03,GL_CURRENT_TEXTURE_COORDS) +GL_ENUM(0x0B10,GL_POINT_SMOOTH) +GL_ENUM(0x0B11,GL_POINT_SIZE) +GL_ENUM(0x0B12,GL_SMOOTH_POINT_SIZE_RANGE) +GL_ENUM(0x0B20,GL_LINE_SMOOTH) +GL_ENUM(0x0B21,GL_LINE_WIDTH) +GL_ENUM(0x0B22,GL_SMOOTH_LINE_WIDTH_RANGE) +GL_ENUM(0x0B44,GL_CULL_FACE) +GL_ENUM(0x0B45,GL_CULL_FACE_MODE) +GL_ENUM(0x0B46,GL_FRONT_FACE) +GL_ENUM(0x0B50,GL_LIGHTING) +GL_ENUM(0x0B52,GL_LIGHT_MODEL_TWO_SIDE) +GL_ENUM(0x0B53,GL_LIGHT_MODEL_AMBIENT) +GL_ENUM(0x0B54,GL_SHADE_MODEL) +GL_ENUM(0x0B57,GL_COLOR_MATERIAL) +GL_ENUM(0x0B60,GL_FOG) +GL_ENUM(0x0B62,GL_FOG_DENSITY) +GL_ENUM(0x0B63,GL_FOG_START) +GL_ENUM(0x0B64,GL_FOG_END) +GL_ENUM(0x0B65,GL_FOG_MODE) +GL_ENUM(0x0B66,GL_FOG_COLOR) +GL_ENUM(0x0B70,GL_DEPTH_RANGE) +GL_ENUM(0x0B71,GL_DEPTH_TEST) +GL_ENUM(0x0B72,GL_DEPTH_WRITEMASK) +GL_ENUM(0x0B73,GL_DEPTH_CLEAR_VALUE) +GL_ENUM(0x0B74,GL_DEPTH_FUNC) +GL_ENUM(0x0B90,GL_STENCIL_TEST) +GL_ENUM(0x0B91,GL_STENCIL_CLEAR_VALUE) +GL_ENUM(0x0B92,GL_STENCIL_FUNC) +GL_ENUM(0x0B93,GL_STENCIL_VALUE_MASK) +GL_ENUM(0x0B94,GL_STENCIL_FAIL) +GL_ENUM(0x0B95,GL_STENCIL_PASS_DEPTH_FAIL) +GL_ENUM(0x0B96,GL_STENCIL_PASS_DEPTH_PASS) +GL_ENUM(0x0B97,GL_STENCIL_REF) +GL_ENUM(0x0B98,GL_STENCIL_WRITEMASK) +GL_ENUM(0x0BA0,GL_MATRIX_MODE) +GL_ENUM(0x0BA1,GL_NORMALIZE) +GL_ENUM(0x0BA2,GL_VIEWPORT) +GL_ENUM(0x0BA3,GL_MODELVIEW_STACK_DEPTH) +GL_ENUM(0x0BA4,GL_PROJECTION_STACK_DEPTH) +GL_ENUM(0x0BA5,GL_TEXTURE_STACK_DEPTH) +GL_ENUM(0x0BA6,GL_MODELVIEW_MATRIX) +GL_ENUM(0x0BA7,GL_PROJECTION_MATRIX) +GL_ENUM(0x0BA8,GL_TEXTURE_MATRIX) +GL_ENUM(0x0BC0,GL_ALPHA_TEST) +GL_ENUM(0x0BC1,GL_ALPHA_TEST_FUNC) +GL_ENUM(0x0BC2,GL_ALPHA_TEST_REF) +GL_ENUM(0x0BD0,GL_DITHER) +GL_ENUM(0x0BE0,GL_BLEND_DST) +GL_ENUM(0x0BE1,GL_BLEND_SRC) +GL_ENUM(0x0BE2,GL_BLEND) +GL_ENUM(0x0BF0,GL_LOGIC_OP_MODE) +GL_ENUM(0x0BF2,GL_COLOR_LOGIC_OP) +GL_ENUM(0x0C10,GL_SCISSOR_BOX) +GL_ENUM(0x0C11,GL_SCISSOR_TEST) +GL_ENUM(0x0C22,GL_COLOR_CLEAR_VALUE) +GL_ENUM(0x0C23,GL_COLOR_WRITEMASK) +GL_ENUM(0x0C50,GL_PERSPECTIVE_CORRECTION_HINT) +GL_ENUM(0x0C51,GL_POINT_SMOOTH_HINT) +GL_ENUM(0x0C52,GL_LINE_SMOOTH_HINT) +GL_ENUM(0x0C54,GL_FOG_HINT) +GL_ENUM(0x0CF5,GL_UNPACK_ALIGNMENT) +GL_ENUM(0x0D05,GL_PACK_ALIGNMENT) +GL_ENUM(0x0D1C,GL_ALPHA_SCALE) +GL_ENUM(0x0D31,GL_MAX_LIGHTS) +GL_ENUM(0x0D32,GL_MAX_CLIP_PLANES) +GL_ENUM(0x0D33,GL_MAX_TEXTURE_SIZE) +GL_ENUM(0x0D36,GL_MAX_MODELVIEW_STACK_DEPTH) +GL_ENUM(0x0D38,GL_MAX_PROJECTION_STACK_DEPTH) +GL_ENUM(0x0D39,GL_MAX_TEXTURE_STACK_DEPTH) +GL_ENUM(0x0D3A,GL_MAX_VIEWPORT_DIMS) +GL_ENUM(0x0D50,GL_SUBPIXEL_BITS) +GL_ENUM(0x0D52,GL_RED_BITS) +GL_ENUM(0x0D53,GL_GREEN_BITS) +GL_ENUM(0x0D54,GL_BLUE_BITS) +GL_ENUM(0x0D55,GL_ALPHA_BITS) +GL_ENUM(0x0D56,GL_DEPTH_BITS) +GL_ENUM(0x0D57,GL_STENCIL_BITS) +GL_ENUM(0x0DE1,GL_TEXTURE_2D) +GL_ENUM(0x1100,GL_DONT_CARE) +GL_ENUM(0x1101,GL_FASTEST) +GL_ENUM(0x1102,GL_NICEST) +GL_ENUM(0x1200,GL_AMBIENT) +GL_ENUM(0x1201,GL_DIFFUSE) +GL_ENUM(0x1202,GL_SPECULAR) +GL_ENUM(0x1203,GL_POSITION) +GL_ENUM(0x1204,GL_SPOT_DIRECTION) +GL_ENUM(0x1205,GL_SPOT_EXPONENT) +GL_ENUM(0x1206,GL_SPOT_CUTOFF) +GL_ENUM(0x1207,GL_CONSTANT_ATTENUATION) +GL_ENUM(0x1208,GL_LINEAR_ATTENUATION) +GL_ENUM(0x1209,GL_QUADRATIC_ATTENUATION) +GL_ENUM(0x1400,GL_BYTE) +GL_ENUM(0x1401,GL_UNSIGNED_BYTE) +GL_ENUM(0x1402,GL_SHORT) +GL_ENUM(0x1403,GL_UNSIGNED_SHORT) +GL_ENUM(0x1404,GL_INT) +GL_ENUM(0x1405,GL_UNSIGNED_INT) +GL_ENUM(0x1406,GL_FLOAT) +GL_ENUM(0x140C,GL_FIXED) +GL_ENUM(0x1500,GL_CLEAR) +GL_ENUM(0x1501,GL_AND) +GL_ENUM(0x1502,GL_AND_REVERSE) +GL_ENUM(0x1503,GL_COPY) +GL_ENUM(0x1504,GL_AND_INVERTED) +GL_ENUM(0x1505,GL_NOOP) +GL_ENUM(0x1506,GL_XOR) +GL_ENUM(0x1507,GL_OR) +GL_ENUM(0x1508,GL_NOR) +GL_ENUM(0x1509,GL_EQUIV) +GL_ENUM(0x150A,GL_INVERT) +GL_ENUM(0x150B,GL_OR_REVERSE) +GL_ENUM(0x150C,GL_COPY_INVERTED) +GL_ENUM(0x150D,GL_OR_INVERTED) +GL_ENUM(0x150E,GL_NAND) +GL_ENUM(0x150F,GL_SET) +GL_ENUM(0x1600,GL_EMISSION) +GL_ENUM(0x1601,GL_SHININESS) +GL_ENUM(0x1602,GL_AMBIENT_AND_DIFFUSE) +GL_ENUM(0x1700,GL_MODELVIEW) +GL_ENUM(0x1701,GL_PROJECTION) +GL_ENUM(0x1702,GL_TEXTURE) +GL_ENUM(0x1800,GL_COLOR_EXT) +GL_ENUM(0x1801,GL_DEPTH_EXT) +GL_ENUM(0x1802,GL_STENCIL_EXT) +GL_ENUM(0x1901,GL_STENCIL_INDEX) +GL_ENUM(0x1902,GL_DEPTH_COMPONENT) +GL_ENUM(0x1906,GL_ALPHA) +GL_ENUM(0x1907,GL_RGB) +GL_ENUM(0x1908,GL_RGBA) +GL_ENUM(0x1909,GL_LUMINANCE) +GL_ENUM(0x190A,GL_LUMINANCE_ALPHA) +GL_ENUM(0x1D00,GL_FLAT) +GL_ENUM(0x1D01,GL_SMOOTH) +GL_ENUM(0x1E00,GL_KEEP) +GL_ENUM(0x1E01,GL_REPLACE) +GL_ENUM(0x1E02,GL_INCR) +GL_ENUM(0x1E03,GL_DECR) +GL_ENUM(0x1F00,GL_VENDOR) +GL_ENUM(0x1F01,GL_RENDERER) +GL_ENUM(0x1F02,GL_VERSION) +GL_ENUM(0x1F03,GL_EXTENSIONS) +GL_ENUM(0x2100,GL_MODULATE) +GL_ENUM(0x2101,GL_DECAL) +GL_ENUM(0x2200,GL_TEXTURE_ENV_MODE) +GL_ENUM(0x2201,GL_TEXTURE_ENV_COLOR) +GL_ENUM(0x2300,GL_TEXTURE_ENV) +GL_ENUM(0x2500,GL_TEXTURE_GEN_MODE_OES) +GL_ENUM(0x2600,GL_NEAREST) +GL_ENUM(0x2601,GL_LINEAR) +GL_ENUM(0x2700,GL_NEAREST_MIPMAP_NEAREST) +GL_ENUM(0x2701,GL_LINEAR_MIPMAP_NEAREST) +GL_ENUM(0x2702,GL_NEAREST_MIPMAP_LINEAR) +GL_ENUM(0x2703,GL_LINEAR_MIPMAP_LINEAR) +GL_ENUM(0x2800,GL_TEXTURE_MAG_FILTER) +GL_ENUM(0x2801,GL_TEXTURE_MIN_FILTER) +GL_ENUM(0x2802,GL_TEXTURE_WRAP_S) +GL_ENUM(0x2803,GL_TEXTURE_WRAP_T) +GL_ENUM(0x2901,GL_REPEAT) +GL_ENUM(0x2A00,GL_POLYGON_OFFSET_UNITS) +GL_ENUM(0x3000,GL_CLIP_PLANE0) +GL_ENUM(0x3001,GL_CLIP_PLANE1) +GL_ENUM(0x3002,GL_CLIP_PLANE2) +GL_ENUM(0x3003,GL_CLIP_PLANE3) +GL_ENUM(0x3004,GL_CLIP_PLANE4) +GL_ENUM(0x3005,GL_CLIP_PLANE5) +GL_ENUM(0x4000,GL_LIGHT0) +GL_ENUM(0x4001,GL_LIGHT1) +GL_ENUM(0x4002,GL_LIGHT2) +GL_ENUM(0x4003,GL_LIGHT3) +GL_ENUM(0x4004,GL_LIGHT4) +GL_ENUM(0x4005,GL_LIGHT5) +GL_ENUM(0x4006,GL_LIGHT6) +GL_ENUM(0x4007,GL_LIGHT7) +GL_ENUM(0x8000,GL_COVERAGE_BUFFER_BIT_NV) +GL_ENUM(0x8001,GL_CONSTANT_COLOR) +GL_ENUM(0x8002,GL_ONE_MINUS_CONSTANT_COLOR) +GL_ENUM(0x8003,GL_CONSTANT_ALPHA) +GL_ENUM(0x8004,GL_ONE_MINUS_CONSTANT_ALPHA) +GL_ENUM(0x8005,GL_BLEND_COLOR) +GL_ENUM(0x8006,GL_FUNC_ADD_OES) +GL_ENUM(0x8007,GL_MIN_EXT) +GL_ENUM(0x8008,GL_MAX_EXT) +GL_ENUM(0x8009,GL_BLEND_EQUATION_RGB_OES) +GL_ENUM(0x800A,GL_FUNC_SUBTRACT_OES) +GL_ENUM(0x800B,GL_FUNC_REVERSE_SUBTRACT_OES) +GL_ENUM(0x8033,GL_UNSIGNED_SHORT_4_4_4_4) +GL_ENUM(0x8034,GL_UNSIGNED_SHORT_5_5_5_1) +GL_ENUM(0x8037,GL_POLYGON_OFFSET_FILL) +GL_ENUM(0x8038,GL_POLYGON_OFFSET_FACTOR) +GL_ENUM(0x803A,GL_RESCALE_NORMAL) +GL_ENUM(0x8051,GL_RGB8_OES) +GL_ENUM(0x8056,GL_RGBA4_OES) +GL_ENUM(0x8057,GL_RGB5_A1_OES) +GL_ENUM(0x8058,GL_RGBA8_OES) +GL_ENUM(0x8069,GL_TEXTURE_BINDING_2D) +GL_ENUM(0x806A,GL_TEXTURE_BINDING_3D_OES) +GL_ENUM(0x806F,GL_TEXTURE_3D_OES) +GL_ENUM(0x8072,GL_TEXTURE_WRAP_R_OES) +GL_ENUM(0x8073,GL_MAX_3D_TEXTURE_SIZE_OES) +GL_ENUM(0x8074,GL_VERTEX_ARRAY) +GL_ENUM(0x8075,GL_NORMAL_ARRAY) +GL_ENUM(0x8076,GL_COLOR_ARRAY) +GL_ENUM(0x8078,GL_TEXTURE_COORD_ARRAY) +GL_ENUM(0x807A,GL_VERTEX_ARRAY_SIZE) +GL_ENUM(0x807B,GL_VERTEX_ARRAY_TYPE) +GL_ENUM(0x807C,GL_VERTEX_ARRAY_STRIDE) +GL_ENUM(0x807E,GL_NORMAL_ARRAY_TYPE) +GL_ENUM(0x807F,GL_NORMAL_ARRAY_STRIDE) +GL_ENUM(0x8081,GL_COLOR_ARRAY_SIZE) +GL_ENUM(0x8082,GL_COLOR_ARRAY_TYPE) +GL_ENUM(0x8083,GL_COLOR_ARRAY_STRIDE) +GL_ENUM(0x8088,GL_TEXTURE_COORD_ARRAY_SIZE) +GL_ENUM(0x8089,GL_TEXTURE_COORD_ARRAY_TYPE) +GL_ENUM(0x808A,GL_TEXTURE_COORD_ARRAY_STRIDE) +GL_ENUM(0x808E,GL_VERTEX_ARRAY_POINTER) +GL_ENUM(0x808F,GL_NORMAL_ARRAY_POINTER) +GL_ENUM(0x8090,GL_COLOR_ARRAY_POINTER) +GL_ENUM(0x8092,GL_TEXTURE_COORD_ARRAY_POINTER) +GL_ENUM(0x809D,GL_MULTISAMPLE) +GL_ENUM(0x809E,GL_SAMPLE_ALPHA_TO_COVERAGE) +GL_ENUM(0x809F,GL_SAMPLE_ALPHA_TO_ONE) +GL_ENUM(0x80A0,GL_SAMPLE_COVERAGE) +GL_ENUM(0x80A8,GL_SAMPLE_BUFFERS) +GL_ENUM(0x80A9,GL_SAMPLES) +GL_ENUM(0x80AA,GL_SAMPLE_COVERAGE_VALUE) +GL_ENUM(0x80AB,GL_SAMPLE_COVERAGE_INVERT) +GL_ENUM(0x80C8,GL_BLEND_DST_RGB_OES) +GL_ENUM(0x80C9,GL_BLEND_SRC_RGB_OES) +GL_ENUM(0x80CA,GL_BLEND_DST_ALPHA_OES) +GL_ENUM(0x80CB,GL_BLEND_SRC_ALPHA_OES) +GL_ENUM(0x80E1,GL_BGRA_EXT) +GL_ENUM(0x8126,GL_POINT_SIZE_MIN) +GL_ENUM(0x8127,GL_POINT_SIZE_MAX) +GL_ENUM(0x8128,GL_POINT_FADE_THRESHOLD_SIZE) +GL_ENUM(0x8129,GL_POINT_DISTANCE_ATTENUATION) +GL_ENUM(0x812F,GL_CLAMP_TO_EDGE) +GL_ENUM(0x8191,GL_GENERATE_MIPMAP) +GL_ENUM(0x8192,GL_GENERATE_MIPMAP_HINT) +GL_ENUM(0x81A5,GL_DEPTH_COMPONENT16_OES) +GL_ENUM(0x81A6,GL_DEPTH_COMPONENT24_OES) +GL_ENUM(0x81A7,GL_DEPTH_COMPONENT32_OES) +GL_ENUM(0x8363,GL_UNSIGNED_SHORT_5_6_5) +GL_ENUM(0x8365,GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) +GL_ENUM(0x8366,GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) +GL_ENUM(0x8368,GL_UNSIGNED_INT_2_10_10_10_REV_EXT) +GL_ENUM(0x8370,GL_MIRRORED_REPEAT_OES) +GL_ENUM(0x83F0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT) +GL_ENUM(0x83F1,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) +GL_ENUM(0x846D,GL_ALIASED_POINT_SIZE_RANGE) +GL_ENUM(0x846E,GL_ALIASED_LINE_WIDTH_RANGE) +GL_ENUM(0x84C0,GL_TEXTURE0) +GL_ENUM(0x84C1,GL_TEXTURE1) +GL_ENUM(0x84C2,GL_TEXTURE2) +GL_ENUM(0x84C3,GL_TEXTURE3) +GL_ENUM(0x84C4,GL_TEXTURE4) +GL_ENUM(0x84C5,GL_TEXTURE5) +GL_ENUM(0x84C6,GL_TEXTURE6) +GL_ENUM(0x84C7,GL_TEXTURE7) +GL_ENUM(0x84C8,GL_TEXTURE8) +GL_ENUM(0x84C9,GL_TEXTURE9) +GL_ENUM(0x84CA,GL_TEXTURE10) +GL_ENUM(0x84CB,GL_TEXTURE11) +GL_ENUM(0x84CC,GL_TEXTURE12) +GL_ENUM(0x84CD,GL_TEXTURE13) +GL_ENUM(0x84CE,GL_TEXTURE14) +GL_ENUM(0x84CF,GL_TEXTURE15) +GL_ENUM(0x84D0,GL_TEXTURE16) +GL_ENUM(0x84D1,GL_TEXTURE17) +GL_ENUM(0x84D2,GL_TEXTURE18) +GL_ENUM(0x84D3,GL_TEXTURE19) +GL_ENUM(0x84D4,GL_TEXTURE20) +GL_ENUM(0x84D5,GL_TEXTURE21) +GL_ENUM(0x84D6,GL_TEXTURE22) +GL_ENUM(0x84D7,GL_TEXTURE23) +GL_ENUM(0x84D8,GL_TEXTURE24) +GL_ENUM(0x84D9,GL_TEXTURE25) +GL_ENUM(0x84DA,GL_TEXTURE26) +GL_ENUM(0x84DB,GL_TEXTURE27) +GL_ENUM(0x84DC,GL_TEXTURE28) +GL_ENUM(0x84DD,GL_TEXTURE29) +GL_ENUM(0x84DE,GL_TEXTURE30) +GL_ENUM(0x84DF,GL_TEXTURE31) +GL_ENUM(0x84E0,GL_ACTIVE_TEXTURE) +GL_ENUM(0x84E1,GL_CLIENT_ACTIVE_TEXTURE) +GL_ENUM(0x84E2,GL_MAX_TEXTURE_UNITS) +GL_ENUM(0x84E7,GL_SUBTRACT) +GL_ENUM(0x84E8,GL_MAX_RENDERBUFFER_SIZE_OES) +GL_ENUM(0x84F2,GL_ALL_COMPLETED_NV) +GL_ENUM(0x84F3,GL_FENCE_STATUS_NV) +GL_ENUM(0x84F4,GL_FENCE_CONDITION_NV) +GL_ENUM(0x84F9,GL_DEPTH_STENCIL_OES) +GL_ENUM(0x84FA,GL_UNSIGNED_INT_24_8_OES) +GL_ENUM(0x84FD,GL_MAX_TEXTURE_LOD_BIAS_EXT) +GL_ENUM(0x84FE,GL_TEXTURE_MAX_ANISOTROPY_EXT) +GL_ENUM(0x84FF,GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) +GL_ENUM(0x8500,GL_TEXTURE_FILTER_CONTROL_EXT) +GL_ENUM(0x8501,GL_TEXTURE_LOD_BIAS_EXT) +GL_ENUM(0x8507,GL_INCR_WRAP_OES) +GL_ENUM(0x8508,GL_DECR_WRAP_OES) +GL_ENUM(0x8511,GL_NORMAL_MAP_OES) +GL_ENUM(0x8512,GL_REFLECTION_MAP_OES) +GL_ENUM(0x8513,GL_TEXTURE_CUBE_MAP_OES) +GL_ENUM(0x8514,GL_TEXTURE_BINDING_CUBE_MAP_OES) +GL_ENUM(0x8515,GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES) +GL_ENUM(0x8516,GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES) +GL_ENUM(0x8517,GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES) +GL_ENUM(0x8518,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES) +GL_ENUM(0x8519,GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES) +GL_ENUM(0x851A,GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES) +GL_ENUM(0x851C,GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES) +GL_ENUM(0x8570,GL_COMBINE) +GL_ENUM(0x8571,GL_COMBINE_RGB) +GL_ENUM(0x8572,GL_COMBINE_ALPHA) +GL_ENUM(0x8573,GL_RGB_SCALE) +GL_ENUM(0x8574,GL_ADD_SIGNED) +GL_ENUM(0x8575,GL_INTERPOLATE) +GL_ENUM(0x8576,GL_CONSTANT) +GL_ENUM(0x8577,GL_PRIMARY_COLOR) +GL_ENUM(0x8578,GL_PREVIOUS) +GL_ENUM(0x8580,GL_SRC0_RGB) +GL_ENUM(0x8581,GL_SRC1_RGB) +GL_ENUM(0x8582,GL_SRC2_RGB) +GL_ENUM(0x8588,GL_SRC0_ALPHA) +GL_ENUM(0x8589,GL_SRC1_ALPHA) +GL_ENUM(0x858A,GL_SRC2_ALPHA) +GL_ENUM(0x8590,GL_OPERAND0_RGB) +GL_ENUM(0x8591,GL_OPERAND1_RGB) +GL_ENUM(0x8592,GL_OPERAND2_RGB) +GL_ENUM(0x8598,GL_OPERAND0_ALPHA) +GL_ENUM(0x8599,GL_OPERAND1_ALPHA) +GL_ENUM(0x859A,GL_OPERAND2_ALPHA) +GL_ENUM(0x85B5,GL_VERTEX_ARRAY_BINDING_OES) +GL_ENUM(0x8622,GL_VERTEX_ATTRIB_ARRAY_ENABLED) +GL_ENUM(0x8623,GL_VERTEX_ATTRIB_ARRAY_SIZE) +GL_ENUM(0x8624,GL_VERTEX_ATTRIB_ARRAY_STRIDE) +GL_ENUM(0x8625,GL_VERTEX_ATTRIB_ARRAY_TYPE) +GL_ENUM(0x8626,GL_CURRENT_VERTEX_ATTRIB) +GL_ENUM(0x8645,GL_VERTEX_ATTRIB_ARRAY_POINTER) +GL_ENUM(0x86A2,GL_NUM_COMPRESSED_TEXTURE_FORMATS) +GL_ENUM(0x86A3,GL_COMPRESSED_TEXTURE_FORMATS) +GL_ENUM(0x86A4,GL_MAX_VERTEX_UNITS_OES) +GL_ENUM(0x86A9,GL_WEIGHT_ARRAY_TYPE_OES) +GL_ENUM(0x86AA,GL_WEIGHT_ARRAY_STRIDE_OES) +GL_ENUM(0x86AB,GL_WEIGHT_ARRAY_SIZE_OES) +GL_ENUM(0x86AC,GL_WEIGHT_ARRAY_POINTER_OES) +GL_ENUM(0x86AD,GL_WEIGHT_ARRAY_OES) +GL_ENUM(0x86AE,GL_DOT3_RGB) +GL_ENUM(0x86AF,GL_DOT3_RGBA) +GL_ENUM(0x8740,GL_Z400_BINARY_AMD) +GL_ENUM(0x8741,GL_PROGRAM_BINARY_LENGTH_OES) +GL_ENUM(0x8764,GL_BUFFER_SIZE) +GL_ENUM(0x8765,GL_BUFFER_USAGE) +GL_ENUM(0x87EE,GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD) +GL_ENUM(0x87F9,GL_3DC_X_AMD) +GL_ENUM(0x87FA,GL_3DC_XY_AMD) +GL_ENUM(0x87FE,GL_NUM_PROGRAM_BINARY_FORMATS_OES) +GL_ENUM(0x87FF,GL_PROGRAM_BINARY_FORMATS_OES) +GL_ENUM(0x8800,GL_STENCIL_BACK_FUNC) +GL_ENUM(0x8801,GL_STENCIL_BACK_FAIL) +GL_ENUM(0x8802,GL_STENCIL_BACK_PASS_DEPTH_FAIL) +GL_ENUM(0x8803,GL_STENCIL_BACK_PASS_DEPTH_PASS) +GL_ENUM(0x8823,GL_WRITEONLY_RENDERING_QCOM) +GL_ENUM(0x883D,GL_BLEND_EQUATION_ALPHA_OES) +GL_ENUM(0x8840,GL_MATRIX_PALETTE_OES) +GL_ENUM(0x8842,GL_MAX_PALETTE_MATRICES_OES) +GL_ENUM(0x8843,GL_CURRENT_PALETTE_MATRIX_OES) +GL_ENUM(0x8844,GL_MATRIX_INDEX_ARRAY_OES) +GL_ENUM(0x8846,GL_MATRIX_INDEX_ARRAY_SIZE_OES) +GL_ENUM(0x8847,GL_MATRIX_INDEX_ARRAY_TYPE_OES) +GL_ENUM(0x8848,GL_MATRIX_INDEX_ARRAY_STRIDE_OES) +GL_ENUM(0x8849,GL_MATRIX_INDEX_ARRAY_POINTER_OES) +GL_ENUM(0x8861,GL_POINT_SPRITE_OES) +GL_ENUM(0x8862,GL_COORD_REPLACE_OES) +GL_ENUM(0x8869,GL_MAX_VERTEX_ATTRIBS) +GL_ENUM(0x886A,GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) +GL_ENUM(0x8872,GL_MAX_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8892,GL_ARRAY_BUFFER) +GL_ENUM(0x8893,GL_ELEMENT_ARRAY_BUFFER) +GL_ENUM(0x8894,GL_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8895,GL_ELEMENT_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8896,GL_VERTEX_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8897,GL_NORMAL_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8898,GL_COLOR_ARRAY_BUFFER_BINDING) +GL_ENUM(0x889A,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING) +GL_ENUM(0x889E,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x889F,GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) +GL_ENUM(0x88B9,GL_WRITE_ONLY_OES) +GL_ENUM(0x88BB,GL_BUFFER_ACCESS_OES) +GL_ENUM(0x88BC,GL_BUFFER_MAPPED_OES) +GL_ENUM(0x88BD,GL_BUFFER_MAP_POINTER_OES) +GL_ENUM(0x88E0,GL_STREAM_DRAW) +GL_ENUM(0x88E4,GL_STATIC_DRAW) +GL_ENUM(0x88E8,GL_DYNAMIC_DRAW) +GL_ENUM(0x88F0,GL_DEPTH24_STENCIL8_OES) +GL_ENUM(0x898A,GL_POINT_SIZE_ARRAY_TYPE_OES) +GL_ENUM(0x898B,GL_POINT_SIZE_ARRAY_STRIDE_OES) +GL_ENUM(0x898C,GL_POINT_SIZE_ARRAY_POINTER_OES) +GL_ENUM(0x898D,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x898E,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x898F,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x8B30,GL_FRAGMENT_SHADER) +GL_ENUM(0x8B31,GL_VERTEX_SHADER) +GL_ENUM(0x8B4C,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8B4D,GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8B4F,GL_SHADER_TYPE) +GL_ENUM(0x8B50,GL_FLOAT_VEC2) +GL_ENUM(0x8B51,GL_FLOAT_VEC3) +GL_ENUM(0x8B52,GL_FLOAT_VEC4) +GL_ENUM(0x8B53,GL_INT_VEC2) +GL_ENUM(0x8B54,GL_INT_VEC3) +GL_ENUM(0x8B55,GL_INT_VEC4) +GL_ENUM(0x8B56,GL_BOOL) +GL_ENUM(0x8B57,GL_BOOL_VEC2) +GL_ENUM(0x8B58,GL_BOOL_VEC3) +GL_ENUM(0x8B59,GL_BOOL_VEC4) +GL_ENUM(0x8B5A,GL_FLOAT_MAT2) +GL_ENUM(0x8B5B,GL_FLOAT_MAT3) +GL_ENUM(0x8B5C,GL_FLOAT_MAT4) +GL_ENUM(0x8B5E,GL_SAMPLER_2D) +GL_ENUM(0x8B5F,GL_SAMPLER_3D_OES) +GL_ENUM(0x8B60,GL_SAMPLER_CUBE) +GL_ENUM(0x8B80,GL_DELETE_STATUS) +GL_ENUM(0x8B81,GL_COMPILE_STATUS) +GL_ENUM(0x8B82,GL_LINK_STATUS) +GL_ENUM(0x8B83,GL_VALIDATE_STATUS) +GL_ENUM(0x8B84,GL_INFO_LOG_LENGTH) +GL_ENUM(0x8B85,GL_ATTACHED_SHADERS) +GL_ENUM(0x8B86,GL_ACTIVE_UNIFORMS) +GL_ENUM(0x8B87,GL_ACTIVE_UNIFORM_MAX_LENGTH) +GL_ENUM(0x8B88,GL_SHADER_SOURCE_LENGTH) +GL_ENUM(0x8B89,GL_ACTIVE_ATTRIBUTES) +GL_ENUM(0x8B8A,GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) +GL_ENUM(0x8B8B,GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES) +GL_ENUM(0x8B8C,GL_SHADING_LANGUAGE_VERSION) +GL_ENUM(0x8B8D,GL_CURRENT_PROGRAM) +GL_ENUM(0x8B90,GL_PALETTE4_RGB8_OES) +GL_ENUM(0x8B91,GL_PALETTE4_RGBA8_OES) +GL_ENUM(0x8B92,GL_PALETTE4_R5_G6_B5_OES) +GL_ENUM(0x8B93,GL_PALETTE4_RGBA4_OES) +GL_ENUM(0x8B94,GL_PALETTE4_RGB5_A1_OES) +GL_ENUM(0x8B95,GL_PALETTE8_RGB8_OES) +GL_ENUM(0x8B96,GL_PALETTE8_RGBA8_OES) +GL_ENUM(0x8B97,GL_PALETTE8_R5_G6_B5_OES) +GL_ENUM(0x8B98,GL_PALETTE8_RGBA4_OES) +GL_ENUM(0x8B99,GL_PALETTE8_RGB5_A1_OES) +GL_ENUM(0x8B9A,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES) +GL_ENUM(0x8B9B,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES) +GL_ENUM(0x8B9C,GL_POINT_SIZE_ARRAY_OES) +GL_ENUM(0x8B9D,GL_TEXTURE_CROP_RECT_OES) +GL_ENUM(0x8B9E,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x8B9F,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x8BC0,GL_COUNTER_TYPE_AMD) +GL_ENUM(0x8BC1,GL_COUNTER_RANGE_AMD) +GL_ENUM(0x8BC2,GL_UNSIGNED_INT64_AMD) +GL_ENUM(0x8BC3,GL_PERCENTAGE_AMD) +GL_ENUM(0x8BC4,GL_PERFMON_RESULT_AVAILABLE_AMD) +GL_ENUM(0x8BC5,GL_PERFMON_RESULT_SIZE_AMD) +GL_ENUM(0x8BC6,GL_PERFMON_RESULT_AMD) +GL_ENUM(0x8BD2,GL_TEXTURE_WIDTH_QCOM) +GL_ENUM(0x8BD3,GL_TEXTURE_HEIGHT_QCOM) +GL_ENUM(0x8BD4,GL_TEXTURE_DEPTH_QCOM) +GL_ENUM(0x8BD5,GL_TEXTURE_INTERNAL_FORMAT_QCOM) +GL_ENUM(0x8BD6,GL_TEXTURE_FORMAT_QCOM) +GL_ENUM(0x8BD7,GL_TEXTURE_TYPE_QCOM) +GL_ENUM(0x8BD8,GL_TEXTURE_IMAGE_VALID_QCOM) +GL_ENUM(0x8BD9,GL_TEXTURE_NUM_LEVELS_QCOM) +GL_ENUM(0x8BDA,GL_TEXTURE_TARGET_QCOM) +GL_ENUM(0x8BDB,GL_TEXTURE_OBJECT_VALID_QCOM) +GL_ENUM(0x8BDC,GL_STATE_RESTORE) +GL_ENUM(0x8C00,GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) +GL_ENUM(0x8C01,GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) +GL_ENUM(0x8C02,GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG) +GL_ENUM(0x8C03,GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) +GL_ENUM(0x8C04,GL_MODULATE_COLOR_IMG) +GL_ENUM(0x8C05,GL_RECIP_ADD_SIGNED_ALPHA_IMG) +GL_ENUM(0x8C06,GL_TEXTURE_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C07,GL_FACTOR_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C08,GL_FRAGMENT_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C09,GL_ADD_BLEND_IMG) +GL_ENUM(0x8C0A,GL_SGX_BINARY_IMG) +GL_ENUM(0x8C92,GL_ATC_RGB_AMD) +GL_ENUM(0x8C93,GL_ATC_RGBA_EXPLICIT_ALPHA_AMD) +GL_ENUM(0x8CA3,GL_STENCIL_BACK_REF) +GL_ENUM(0x8CA4,GL_STENCIL_BACK_VALUE_MASK) +GL_ENUM(0x8CA5,GL_STENCIL_BACK_WRITEMASK) +GL_ENUM(0x8CA6,GL_FRAMEBUFFER_BINDING_OES) +GL_ENUM(0x8CA7,GL_RENDERBUFFER_BINDING_OES) +GL_ENUM(0x8CD0,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES) +GL_ENUM(0x8CD1,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES) +GL_ENUM(0x8CD2,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES) +GL_ENUM(0x8CD3,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES) +GL_ENUM(0x8CD4,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES) +GL_ENUM(0x8CD5,GL_FRAMEBUFFER_COMPLETE_OES) +GL_ENUM(0x8CD6,GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES) +GL_ENUM(0x8CD7,GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES) +GL_ENUM(0x8CD9,GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES) +GL_ENUM(0x8CDA,GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES) +GL_ENUM(0x8CDD,GL_FRAMEBUFFER_UNSUPPORTED_OES) +GL_ENUM(0x8CE0,GL_COLOR_ATTACHMENT0_OES) +GL_ENUM(0x8D00,GL_DEPTH_ATTACHMENT_OES) +GL_ENUM(0x8D20,GL_STENCIL_ATTACHMENT_OES) +GL_ENUM(0x8D40,GL_FRAMEBUFFER_OES) +GL_ENUM(0x8D41,GL_RENDERBUFFER_OES) +GL_ENUM(0x8D42,GL_RENDERBUFFER_WIDTH_OES) +GL_ENUM(0x8D43,GL_RENDERBUFFER_HEIGHT_OES) +GL_ENUM(0x8D44,GL_RENDERBUFFER_INTERNAL_FORMAT_OES) +GL_ENUM(0x8D46,GL_STENCIL_INDEX1_OES) +GL_ENUM(0x8D47,GL_STENCIL_INDEX4_OES) +GL_ENUM(0x8D48,GL_STENCIL_INDEX8_OES) +GL_ENUM(0x8D50,GL_RENDERBUFFER_RED_SIZE_OES) +GL_ENUM(0x8D51,GL_RENDERBUFFER_GREEN_SIZE_OES) +GL_ENUM(0x8D52,GL_RENDERBUFFER_BLUE_SIZE_OES) +GL_ENUM(0x8D53,GL_RENDERBUFFER_ALPHA_SIZE_OES) +GL_ENUM(0x8D54,GL_RENDERBUFFER_DEPTH_SIZE_OES) +GL_ENUM(0x8D55,GL_RENDERBUFFER_STENCIL_SIZE_OES) +GL_ENUM(0x8D60,GL_TEXTURE_GEN_STR_OES) +GL_ENUM(0x8D61,GL_HALF_FLOAT_OES) +GL_ENUM(0x8D62,GL_RGB565_OES) +GL_ENUM(0x8D64,GL_ETC1_RGB8_OES) +GL_ENUM(0x8D65,GL_TEXTURE_EXTERNAL_OES) +GL_ENUM(0x8D66,GL_SAMPLER_EXTERNAL_OES) +GL_ENUM(0x8D67,GL_TEXTURE_BINDING_EXTERNAL_OES) +GL_ENUM(0x8D68,GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES) +GL_ENUM(0x8DF0,GL_LOW_FLOAT) +GL_ENUM(0x8DF1,GL_MEDIUM_FLOAT) +GL_ENUM(0x8DF2,GL_HIGH_FLOAT) +GL_ENUM(0x8DF3,GL_LOW_INT) +GL_ENUM(0x8DF4,GL_MEDIUM_INT) +GL_ENUM(0x8DF5,GL_HIGH_INT) +GL_ENUM(0x8DF6,GL_UNSIGNED_INT_10_10_10_2_OES) +GL_ENUM(0x8DF7,GL_INT_10_10_10_2_OES) +GL_ENUM(0x8DF8,GL_SHADER_BINARY_FORMATS) +GL_ENUM(0x8DF9,GL_NUM_SHADER_BINARY_FORMATS) +GL_ENUM(0x8DFA,GL_SHADER_COMPILER) +GL_ENUM(0x8DFB,GL_MAX_VERTEX_UNIFORM_VECTORS) +GL_ENUM(0x8DFC,GL_MAX_VARYING_VECTORS) +GL_ENUM(0x8DFD,GL_MAX_FRAGMENT_UNIFORM_VECTORS) +GL_ENUM(0x8E2C,GL_DEPTH_COMPONENT16_NONLINEAR_NV) +GL_ENUM(0x8ED0,GL_COVERAGE_COMPONENT_NV) +GL_ENUM(0x8ED1,GL_COVERAGE_COMPONENT4_NV) +GL_ENUM(0x8ED2,GL_COVERAGE_ATTACHMENT_NV) +GL_ENUM(0x8ED3,GL_COVERAGE_BUFFERS_NV) +GL_ENUM(0x8ED4,GL_COVERAGE_SAMPLES_NV) +GL_ENUM(0x8ED5,GL_COVERAGE_ALL_FRAGMENTS_NV) +GL_ENUM(0x8ED6,GL_COVERAGE_EDGE_FRAGMENTS_NV) +GL_ENUM(0x8ED7,GL_COVERAGE_AUTOMATIC_NV) +GL_ENUM(0x8FA0,GL_PERFMON_GLOBAL_MODE_QCOM) +GL_ENUM(0x9130,GL_SGX_PROGRAM_BINARY_IMG) +GL_ENUM(0x9133,GL_RENDERBUFFER_SAMPLES_IMG) +GL_ENUM(0x9134,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG) +GL_ENUM(0x9135,GL_MAX_SAMPLES_IMG) +GL_ENUM(0x9136,GL_TEXTURE_SAMPLES_IMG) diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index 1ab58cc..812e26d 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -141,6 +141,11 @@ static gl_hooks_t const* getGlThreadSpecific() { #endif +#if EGL_TRACE + +extern gl_hooks_t const* getGLTraceThreadSpecific(); + +#endif // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles index 120cb4b..50bbf08 100755 --- a/opengl/libs/tools/genfiles +++ b/opengl/libs/tools/genfiles @@ -31,3 +31,14 @@ cat /tmp/gl_entries.in \ | sort -t, -k2 \ | awk -F, '!_[$2]++' \ > ../entries.in + +./gltracegen ../entries.in >../trace.in + +cat ../../include/GLES/gl.h \ + ../../include/GLES/glext.h \ + ../../include/GLES2/gl2.h \ + ../../include/GLES2/gl2ext.h \ + | ./glenumsgen \ + | sort \ + > ../enums.in + diff --git a/opengl/libs/tools/glenumsgen b/opengl/libs/tools/glenumsgen new file mode 100755 index 0000000..2ae5fbf --- /dev/null +++ b/opengl/libs/tools/glenumsgen @@ -0,0 +1,38 @@ +#! /usr/bin/perl +# +# Copyright (C) 2010 Google Inc. +# +# 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. + +use strict; + +my %enumHash = (); + +while (my $line = <STDIN>) { + next if $line =~ /^\//; + # Skip bitfield definitions. + next if $line =~ /_BIT(\d+_|\s+)/; + if ($line !~ /^#define\s+(\S+)\s+(0x\S+)/) { + next; + } + my $enumName = $1; + my $enumValue = $2; + next if exists($enumHash { $enumValue }); + $enumHash { $enumValue } = $enumName; + printf("GL_ENUM(%s,%s)\n", $enumValue, $enumName); +} + + + + + diff --git a/opengl/libs/tools/gltracegen b/opengl/libs/tools/gltracegen new file mode 100755 index 0000000..da42653 --- /dev/null +++ b/opengl/libs/tools/gltracegen @@ -0,0 +1,95 @@ +#! /usr/bin/perl +# +# Copyright (C) 2010 Google Inc. +# +# 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. + +use strict; + +sub rtrim($) +{ + my $string = shift; + $string =~ s/\s+$//; + return $string; +} + +while (my $line = <>) { + next if $line =~ /^\//; + next if $line =~ /^#/; + next if $line =~ /^\s*$/; + if ($line !~ /^GL_ENTRY\(([^,]+), ([^,]+), ([^\)]+)\)/) { + next; + } + my $type = $1; + my $name = $2; + my $args = $3; + + my @args = split ',', $args; + my $len = scalar(@args); + my $nonVoidArgLen = 0; + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + $nonVoidArgLen++; + } + } + if ($type eq "void") { + printf("TRACE_GL_VOID("); + } else { + printf("TRACE_GL(%s, ", $type); + } + + printf("%s, (%s), (", $name, $args); + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + if ($num > 0) { + print ", "; + } + # + # extract the name from the parameter + # type name + # const type *name + # type *name + # type name[4] + # + if ($args[$num] =~ /(\S+\s)+\**\s*([\w]+)/) { + printf("%s", $2); + } + } + } + printf("), %d", $nonVoidArgLen); + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + # + # extract the name from the parameter + # type name + # const type *name + # type *name + # type name[4] + # + my $arg = $args[$num]; + if ($arg =~ /(\S+\s)+\**\s*([\w]+)/) { + my $name = $2; + if ($arg =~ /((const )*(\S+\s)+\**)\s*([\w]+)/) { + my $type = rtrim($1); + printf(", \"%s\", %s", $type, $name); + } + } + } + } + printf(")\n"); +} + + + + + diff --git a/opengl/libs/trace.in b/opengl/libs/trace.in new file mode 100644 index 0000000..3d492af --- /dev/null +++ b/opengl/libs/trace.in @@ -0,0 +1,376 @@ +TRACE_GL_VOID(glActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture) +TRACE_GL_VOID(glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref) +TRACE_GL_VOID(glAlphaFuncx, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref) +TRACE_GL_VOID(glAlphaFuncxOES, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref) +TRACE_GL_VOID(glAttachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader) +TRACE_GL_VOID(glBeginPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor) +TRACE_GL_VOID(glBindAttribLocation, (GLuint program, GLuint index, const GLchar* name), (program, index, name), 3, "GLuint", program, "GLuint", index, "const GLchar*", name) +TRACE_GL_VOID(glBindBuffer, (GLenum target, GLuint buffer), (target, buffer), 2, "GLenum", target, "GLuint", buffer) +TRACE_GL_VOID(glBindFramebuffer, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer) +TRACE_GL_VOID(glBindFramebufferOES, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer) +TRACE_GL_VOID(glBindRenderbuffer, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer) +TRACE_GL_VOID(glBindRenderbufferOES, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer) +TRACE_GL_VOID(glBindTexture, (GLenum target, GLuint texture), (target, texture), 2, "GLenum", target, "GLuint", texture) +TRACE_GL_VOID(glBindVertexArrayOES, (GLuint array), (array), 1, "GLuint", array) +TRACE_GL_VOID(glBlendColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha) +TRACE_GL_VOID(glBlendEquation, ( GLenum mode ), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glBlendEquationOES, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glBlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha) +TRACE_GL_VOID(glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha) +TRACE_GL_VOID(glBlendFunc, (GLenum sfactor, GLenum dfactor), (sfactor, dfactor), 2, "GLenum", sfactor, "GLenum", dfactor) +TRACE_GL_VOID(glBlendFuncSeparate, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha) +TRACE_GL_VOID(glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha) +TRACE_GL_VOID(glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage), (target, size, data, usage), 4, "GLenum", target, "GLsizeiptr", size, "const GLvoid *", data, "GLenum", usage) +TRACE_GL_VOID(glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data), (target, offset, size, data), 4, "GLenum", target, "GLintptr", offset, "GLsizeiptr", size, "const GLvoid *", data) +TRACE_GL(GLenum, glCheckFramebufferStatus, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL(GLenum, glCheckFramebufferStatusOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glClear, (GLbitfield mask), (mask), 1, "GLbitfield", mask) +TRACE_GL_VOID(glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha) +TRACE_GL_VOID(glClearColorx, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha) +TRACE_GL_VOID(glClearColorxOES, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha) +TRACE_GL_VOID(glClearDepthf, (GLclampf depth), (depth), 1, "GLclampf", depth) +TRACE_GL_VOID(glClearDepthfOES, (GLclampf depth), (depth), 1, "GLclampf", depth) +TRACE_GL_VOID(glClearDepthx, (GLclampx depth), (depth), 1, "GLclampx", depth) +TRACE_GL_VOID(glClearDepthxOES, (GLclampx depth), (depth), 1, "GLclampx", depth) +TRACE_GL_VOID(glClearStencil, (GLint s), (s), 1, "GLint", s) +TRACE_GL_VOID(glClientActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture) +TRACE_GL_VOID(glClipPlanef, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation) +TRACE_GL_VOID(glClipPlanefIMG, (GLenum p, const GLfloat *eqn), (p, eqn), 2, "GLenum", p, "const GLfloat *", eqn) +TRACE_GL_VOID(glClipPlanefOES, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation) +TRACE_GL_VOID(glClipPlanex, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation) +TRACE_GL_VOID(glClipPlanexIMG, (GLenum p, const GLfixed *eqn), (p, eqn), 2, "GLenum", p, "const GLfixed *", eqn) +TRACE_GL_VOID(glClipPlanexOES, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation) +TRACE_GL_VOID(glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), (red, green, blue, alpha), 4, "GLfloat", red, "GLfloat", green, "GLfloat", blue, "GLfloat", alpha) +TRACE_GL_VOID(glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha), (red, green, blue, alpha), 4, "GLubyte", red, "GLubyte", green, "GLubyte", blue, "GLubyte", alpha) +TRACE_GL_VOID(glColor4x, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha) +TRACE_GL_VOID(glColor4xOES, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha) +TRACE_GL_VOID(glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha), (red, green, blue, alpha), 4, "GLboolean", red, "GLboolean", green, "GLboolean", blue, "GLboolean", alpha) +TRACE_GL_VOID(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glCompileShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL_VOID(glCompressedTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data), (target, level, internalformat, width, height, border, imageSize, data), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLsizei", imageSize, "const GLvoid *", data) +TRACE_GL_VOID(glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data), (target, level, internalformat, width, height, depth, border, imageSize, data), 9, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLsizei", imageSize, "const GLvoid*", data) +TRACE_GL_VOID(glCompressedTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data), (target, level, xoffset, yoffset, width, height, format, imageSize, data), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLsizei", imageSize, "const GLvoid *", data) +TRACE_GL_VOID(glCompressedTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLsizei", imageSize, "const GLvoid*", data) +TRACE_GL_VOID(glCopyTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border), (target, level, internalformat, x, y, width, height, border), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLint", border) +TRACE_GL_VOID(glCopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, x, y, width, height), 8, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, zoffset, x, y, width, height), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glCoverageMaskNV, (GLboolean mask), (mask), 1, "GLboolean", mask) +TRACE_GL_VOID(glCoverageOperationNV, (GLenum operation), (operation), 1, "GLenum", operation) +TRACE_GL(GLuint, glCreateProgram, (void), (), 0) +TRACE_GL(GLuint, glCreateShader, (GLenum type), (type), 1, "GLenum", type) +TRACE_GL_VOID(glCullFace, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex), (matrixpaletteindex), 1, "GLuint", matrixpaletteindex) +TRACE_GL_VOID(glDeleteBuffers, (GLsizei n, const GLuint *buffers), (n, buffers), 2, "GLsizei", n, "const GLuint *", buffers) +TRACE_GL_VOID(glDeleteFencesNV, (GLsizei n, const GLuint *fences), (n, fences), 2, "GLsizei", n, "const GLuint *", fences) +TRACE_GL_VOID(glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers) +TRACE_GL_VOID(glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers) +TRACE_GL_VOID(glDeletePerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors) +TRACE_GL_VOID(glDeleteProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glDeleteRenderbuffers, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers) +TRACE_GL_VOID(glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers) +TRACE_GL_VOID(glDeleteShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL_VOID(glDeleteTextures, (GLsizei n, const GLuint *textures), (n, textures), 2, "GLsizei", n, "const GLuint *", textures) +TRACE_GL_VOID(glDeleteVertexArraysOES, (GLsizei n, const GLuint *arrays), (n, arrays), 2, "GLsizei", n, "const GLuint *", arrays) +TRACE_GL_VOID(glDepthFunc, (GLenum func), (func), 1, "GLenum", func) +TRACE_GL_VOID(glDepthMask, (GLboolean flag), (flag), 1, "GLboolean", flag) +TRACE_GL_VOID(glDepthRangef, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar) +TRACE_GL_VOID(glDepthRangefOES, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar) +TRACE_GL_VOID(glDepthRangex, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar) +TRACE_GL_VOID(glDepthRangexOES, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar) +TRACE_GL_VOID(glDetachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader) +TRACE_GL_VOID(glDisable, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL_VOID(glDisableClientState, (GLenum array), (array), 1, "GLenum", array) +TRACE_GL_VOID(glDisableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl) +TRACE_GL_VOID(glDisableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index) +TRACE_GL_VOID(glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum *attachments), (target, numAttachments, attachments), 3, "GLenum", target, "GLsizei", numAttachments, "const GLenum *", attachments) +TRACE_GL_VOID(glDrawArrays, (GLenum mode, GLint first, GLsizei count), (mode, first, count), 3, "GLenum", mode, "GLint", first, "GLsizei", count) +TRACE_GL_VOID(glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices), (mode, count, type, indices), 4, "GLenum", mode, "GLsizei", count, "GLenum", type, "const GLvoid *", indices) +TRACE_GL_VOID(glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), (x, y, z, width, height), 5, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", width, "GLfloat", height) +TRACE_GL_VOID(glDrawTexfvOES, (const GLfloat *coords), (coords), 1, "const GLfloat *", coords) +TRACE_GL_VOID(glDrawTexiOES, (GLint x, GLint y, GLint z, GLint width, GLint height), (x, y, z, width, height), 5, "GLint", x, "GLint", y, "GLint", z, "GLint", width, "GLint", height) +TRACE_GL_VOID(glDrawTexivOES, (const GLint *coords), (coords), 1, "const GLint *", coords) +TRACE_GL_VOID(glDrawTexsOES, (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height), (x, y, z, width, height), 5, "GLshort", x, "GLshort", y, "GLshort", z, "GLshort", width, "GLshort", height) +TRACE_GL_VOID(glDrawTexsvOES, (const GLshort *coords), (coords), 1, "const GLshort *", coords) +TRACE_GL_VOID(glDrawTexxOES, (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height), (x, y, z, width, height), 5, "GLfixed", x, "GLfixed", y, "GLfixed", z, "GLfixed", width, "GLfixed", height) +TRACE_GL_VOID(glDrawTexxvOES, (const GLfixed *coords), (coords), 1, "const GLfixed *", coords) +TRACE_GL_VOID(glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image) +TRACE_GL_VOID(glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image) +TRACE_GL_VOID(glEnable, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL_VOID(glEnableClientState, (GLenum array), (array), 1, "GLenum", array) +TRACE_GL_VOID(glEnableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl) +TRACE_GL_VOID(glEnableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index) +TRACE_GL_VOID(glEndPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor) +TRACE_GL_VOID(glEndTilingQCOM, (GLbitfield preserveMask), (preserveMask), 1, "GLbitfield", preserveMask) +TRACE_GL_VOID(glExtGetBufferPointervQCOM, (GLenum target, GLvoid **params), (target, params), 2, "GLenum", target, "GLvoid **", params) +TRACE_GL_VOID(glExtGetBuffersQCOM, (GLuint *buffers, GLint maxBuffers, GLint *numBuffers), (buffers, maxBuffers, numBuffers), 3, "GLuint *", buffers, "GLint", maxBuffers, "GLint *", numBuffers) +TRACE_GL_VOID(glExtGetFramebuffersQCOM, (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers), (framebuffers, maxFramebuffers, numFramebuffers), 3, "GLuint *", framebuffers, "GLint", maxFramebuffers, "GLint *", numFramebuffers) +TRACE_GL_VOID(glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, GLchar *source, GLint *length), (program, shadertype, source, length), 4, "GLuint", program, "GLenum", shadertype, "GLchar *", source, "GLint *", length) +TRACE_GL_VOID(glExtGetProgramsQCOM, (GLuint *programs, GLint maxPrograms, GLint *numPrograms), (programs, maxPrograms, numPrograms), 3, "GLuint *", programs, "GLint", maxPrograms, "GLint *", numPrograms) +TRACE_GL_VOID(glExtGetRenderbuffersQCOM, (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers), (renderbuffers, maxRenderbuffers, numRenderbuffers), 3, "GLuint *", renderbuffers, "GLint", maxRenderbuffers, "GLint *", numRenderbuffers) +TRACE_GL_VOID(glExtGetShadersQCOM, (GLuint *shaders, GLint maxShaders, GLint *numShaders), (shaders, maxShaders, numShaders), 3, "GLuint *", shaders, "GLint", maxShaders, "GLint *", numShaders) +TRACE_GL_VOID(glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params), (texture, face, level, pname, params), 5, "GLuint", texture, "GLenum", face, "GLint", level, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "GLvoid *", texels) +TRACE_GL_VOID(glExtGetTexturesQCOM, (GLuint *textures, GLint maxTextures, GLint *numTextures), (textures, maxTextures, numTextures), 3, "GLuint *", textures, "GLint", maxTextures, "GLint *", numTextures) +TRACE_GL(GLboolean, glExtIsProgramBinaryQCOM, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glFinish, (void), (), 0) +TRACE_GL_VOID(glFinishFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL_VOID(glFlush, (void), (), 0) +TRACE_GL_VOID(glFogf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glFogfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glFogx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glFogxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glFogxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glFogxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer) +TRACE_GL_VOID(glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer) +TRACE_GL_VOID(glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level) +TRACE_GL_VOID(glFramebufferTexture2DMultisampleIMG, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples) +TRACE_GL_VOID(glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level) +TRACE_GL_VOID(glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target, attachment, textarget, texture, level, zoffset), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLint", zoffset) +TRACE_GL_VOID(glFrontFace, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glFrustumf, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glFrustumfOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glFrustumx, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glFrustumxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glGenBuffers, (GLsizei n, GLuint *buffers), (n, buffers), 2, "GLsizei", n, "GLuint *", buffers) +TRACE_GL_VOID(glGenFencesNV, (GLsizei n, GLuint *fences), (n, fences), 2, "GLsizei", n, "GLuint *", fences) +TRACE_GL_VOID(glGenFramebuffers, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers) +TRACE_GL_VOID(glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers) +TRACE_GL_VOID(glGenPerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors) +TRACE_GL_VOID(glGenRenderbuffers, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers) +TRACE_GL_VOID(glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers) +TRACE_GL_VOID(glGenTextures, (GLsizei n, GLuint *textures), (n, textures), 2, "GLsizei", n, "GLuint *", textures) +TRACE_GL_VOID(glGenVertexArraysOES, (GLsizei n, GLuint *arrays), (n, arrays), 2, "GLsizei", n, "GLuint *", arrays) +TRACE_GL_VOID(glGenerateMipmap, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glGenerateMipmapOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glGetActiveAttrib, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name) +TRACE_GL_VOID(glGetActiveUniform, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name) +TRACE_GL_VOID(glGetAttachedShaders, (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders), (program, maxcount, count, shaders), 4, "GLuint", program, "GLsizei", maxcount, "GLsizei*", count, "GLuint*", shaders) +TRACE_GL(int, glGetAttribLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name) +TRACE_GL_VOID(glGetBooleanv, (GLenum pname, GLboolean *params), (pname, params), 2, "GLenum", pname, "GLboolean *", params) +TRACE_GL_VOID(glGetBufferParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetBufferPointervOES, (GLenum target, GLenum pname, GLvoid ** params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLvoid **", params) +TRACE_GL_VOID(glGetClipPlanef, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn) +TRACE_GL_VOID(glGetClipPlanefOES, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn) +TRACE_GL_VOID(glGetClipPlanex, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn) +TRACE_GL_VOID(glGetClipPlanexOES, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn) +TRACE_GL_VOID(glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString), (driverControl, bufSize, length, driverControlString), 4, "GLuint", driverControl, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", driverControlString) +TRACE_GL_VOID(glGetDriverControlsQCOM, (GLint *num, GLsizei size, GLuint *driverControls), (num, size, driverControls), 3, "GLint *", num, "GLsizei", size, "GLuint *", driverControls) +TRACE_GL(GLenum, glGetError, (void), (), 0) +TRACE_GL_VOID(glGetFenceivNV, (GLuint fence, GLenum pname, GLint *params), (fence, pname, params), 3, "GLuint", fence, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetFixedv, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetFixedvOES, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetFloatv, (GLenum pname, GLfloat *params), (pname, params), 2, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetIntegerv, (GLenum pname, GLint *params), (pname, params), 2, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetLightfv, (GLenum light, GLenum pname, GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetLightxv, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetMaterialxv, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten), (monitor, pname, dataSize, data, bytesWritten), 5, "GLuint", monitor, "GLenum", pname, "GLsizei", dataSize, "GLuint *", data, "GLint *", bytesWritten) +TRACE_GL_VOID(glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, GLvoid *data), (group, counter, pname, data), 4, "GLuint", group, "GLuint", counter, "GLenum", pname, "GLvoid *", data) +TRACE_GL_VOID(glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString), (group, counter, bufSize, length, counterString), 5, "GLuint", group, "GLuint", counter, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", counterString) +TRACE_GL_VOID(glGetPerfMonitorCountersAMD, (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters), (group, numCounters, maxActiveCounters, counterSize, counters), 5, "GLuint", group, "GLint *", numCounters, "GLint *", maxActiveCounters, "GLsizei", counterSize, "GLuint *", counters) +TRACE_GL_VOID(glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString), (group, bufSize, length, groupString), 4, "GLuint", group, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", groupString) +TRACE_GL_VOID(glGetPerfMonitorGroupsAMD, (GLint *numGroups, GLsizei groupsSize, GLuint *groups), (numGroups, groupsSize, groups), 3, "GLint *", numGroups, "GLsizei", groupsSize, "GLuint *", groups) +TRACE_GL_VOID(glGetPointerv, (GLenum pname, GLvoid **params), (pname, params), 2, "GLenum", pname, "GLvoid **", params) +TRACE_GL_VOID(glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary), (program, bufSize, length, binaryFormat, binary), 5, "GLuint", program, "GLsizei", bufSize, "GLsizei *", length, "GLenum *", binaryFormat, "GLvoid *", binary) +TRACE_GL_VOID(glGetProgramInfoLog, (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog), 4, "GLuint", program, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog) +TRACE_GL_VOID(glGetProgramiv, (GLuint program, GLenum pname, GLint* params), (program, pname, params), 3, "GLuint", program, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetShaderInfoLog, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog) +TRACE_GL_VOID(glGetShaderPrecisionFormat, (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision), (shadertype, precisiontype, range, precision), 4, "GLenum", shadertype, "GLenum", precisiontype, "GLint*", range, "GLint*", precision) +TRACE_GL_VOID(glGetShaderSource, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source), (shader, bufsize, length, source), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", source) +TRACE_GL_VOID(glGetShaderiv, (GLuint shader, GLenum pname, GLint* params), (shader, pname, params), 3, "GLuint", shader, "GLenum", pname, "GLint*", params) +TRACE_GL(const GLubyte *, glGetString, (GLenum name), (name), 1, "GLenum", name) +TRACE_GL_VOID(glGetTexEnvfv, (GLenum env, GLenum pname, GLfloat *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexEnviv, (GLenum env, GLenum pname, GLint *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexEnvxv, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexEnvxvOES, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexGenfvOES, (GLenum coord, GLenum pname, GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexGenivOES, (GLenum coord, GLenum pname, GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexGenxvOES, (GLenum coord, GLenum pname, GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexParameterxv, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexParameterxvOES, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params) +TRACE_GL(int, glGetUniformLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name) +TRACE_GL_VOID(glGetUniformfv, (GLuint program, GLint location, GLfloat* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLfloat*", params) +TRACE_GL_VOID(glGetUniformiv, (GLuint program, GLint location, GLint* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLint*", params) +TRACE_GL_VOID(glGetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid** pointer), (index, pname, pointer), 3, "GLuint", index, "GLenum", pname, "GLvoid**", pointer) +TRACE_GL_VOID(glGetVertexAttribfv, (GLuint index, GLenum pname, GLfloat* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLfloat*", params) +TRACE_GL_VOID(glGetVertexAttribiv, (GLuint index, GLenum pname, GLint* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glHint, (GLenum target, GLenum mode), (target, mode), 2, "GLenum", target, "GLenum", mode) +TRACE_GL(GLboolean, glIsBuffer, (GLuint buffer), (buffer), 1, "GLuint", buffer) +TRACE_GL(GLboolean, glIsEnabled, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL(GLboolean, glIsFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL(GLboolean, glIsFramebuffer, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer) +TRACE_GL(GLboolean, glIsFramebufferOES, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer) +TRACE_GL(GLboolean, glIsProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL(GLboolean, glIsRenderbuffer, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer) +TRACE_GL(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer) +TRACE_GL(GLboolean, glIsShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL(GLboolean, glIsTexture, (GLuint texture), (texture), 1, "GLuint", texture) +TRACE_GL(GLboolean, glIsVertexArrayOES, (GLuint array), (array), 1, "GLuint", array) +TRACE_GL_VOID(glLightModelf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glLightModelfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glLightModelx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightModelxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightModelxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightModelxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightf, (GLenum light, GLenum pname, GLfloat param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glLightfv, (GLenum light, GLenum pname, const GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glLightx, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightxOES, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightxv, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightxvOES, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLineWidth, (GLfloat width), (width), 1, "GLfloat", width) +TRACE_GL_VOID(glLineWidthx, (GLfixed width), (width), 1, "GLfixed", width) +TRACE_GL_VOID(glLineWidthxOES, (GLfixed width), (width), 1, "GLfixed", width) +TRACE_GL_VOID(glLinkProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glLoadIdentity, (void), (), 0) +TRACE_GL_VOID(glLoadMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m) +TRACE_GL_VOID(glLoadMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glLoadMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glLoadPaletteFromModelViewMatrixOES, (void), (), 0) +TRACE_GL_VOID(glLogicOp, (GLenum opcode), (opcode), 1, "GLenum", opcode) +TRACE_GL(void*, glMapBufferOES, (GLenum target, GLenum access), (target, access), 2, "GLenum", target, "GLenum", access) +TRACE_GL_VOID(glMaterialf, (GLenum face, GLenum pname, GLfloat param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glMaterialfv, (GLenum face, GLenum pname, const GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glMaterialx, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glMaterialxOES, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glMaterialxv, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glMaterialxvOES, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glMatrixIndexPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glMatrixMode, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glMultMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m) +TRACE_GL_VOID(glMultMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glMultMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glMultiDrawArraysEXT, (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount), (mode, first, count, primcount), 4, "GLenum", mode, "GLint *", first, "GLsizei *", count, "GLsizei", primcount) +TRACE_GL_VOID(glMultiDrawElementsEXT, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount), (mode, count, type, indices, primcount), 5, "GLenum", mode, "const GLsizei *", count, "GLenum", type, "const GLvoid* *", indices, "GLsizei", primcount) +TRACE_GL_VOID(glMultiTexCoord4f, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), (target, s, t, r, q), 5, "GLenum", target, "GLfloat", s, "GLfloat", t, "GLfloat", r, "GLfloat", q) +TRACE_GL_VOID(glMultiTexCoord4x, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q) +TRACE_GL_VOID(glMultiTexCoord4xOES, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q) +TRACE_GL_VOID(glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz), (nx, ny, nz), 3, "GLfloat", nx, "GLfloat", ny, "GLfloat", nz) +TRACE_GL_VOID(glNormal3x, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz) +TRACE_GL_VOID(glNormal3xOES, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz) +TRACE_GL_VOID(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glOrthofOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glOrthox, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glOrthoxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glPixelStorei, (GLenum pname, GLint param), (pname, param), 2, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glPointParameterf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glPointParameterfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glPointParameterx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glPointParameterxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glPointParameterxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glPointParameterxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glPointSize, (GLfloat size), (size), 1, "GLfloat", size) +TRACE_GL_VOID(glPointSizePointerOES, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glPointSizex, (GLfixed size), (size), 1, "GLfixed", size) +TRACE_GL_VOID(glPointSizexOES, (GLfixed size), (size), 1, "GLfixed", size) +TRACE_GL_VOID(glPolygonOffset, (GLfloat factor, GLfloat units), (factor, units), 2, "GLfloat", factor, "GLfloat", units) +TRACE_GL_VOID(glPolygonOffsetx, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units) +TRACE_GL_VOID(glPolygonOffsetxOES, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units) +TRACE_GL_VOID(glPopMatrix, (void), (), 0) +TRACE_GL_VOID(glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length), (program, binaryFormat, binary, length), 4, "GLuint", program, "GLenum", binaryFormat, "const GLvoid *", binary, "GLint", length) +TRACE_GL_VOID(glPushMatrix, (void), (), 0) +TRACE_GL(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]), (mantissa, exponent), 2, "GLfixed", mantissa, "GLint", exponent) +TRACE_GL_VOID(glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels), (x, y, width, height, format, type, pixels), 7, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "GLvoid *", pixels) +TRACE_GL_VOID(glReleaseShaderCompiler, (void), (), 0) +TRACE_GL_VOID(glRenderbufferStorage, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRenderbufferStorageMultisampleIMG, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z), (angle, x, y, z), 4, "GLfloat", angle, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glRotatex, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glSampleCoverage, (GLclampf value, GLboolean invert), (value, invert), 2, "GLclampf", value, "GLboolean", invert) +TRACE_GL_VOID(glSampleCoveragex, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert) +TRACE_GL_VOID(glSampleCoveragexOES, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert) +TRACE_GL_VOID(glScalef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glScalex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glScalexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glScissor, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList), (monitor, enable, group, numCounters, countersList), 5, "GLuint", monitor, "GLboolean", enable, "GLuint", group, "GLint", numCounters, "GLuint *", countersList) +TRACE_GL_VOID(glSetFenceNV, (GLuint fence, GLenum condition), (fence, condition), 2, "GLuint", fence, "GLenum", condition) +TRACE_GL_VOID(glShadeModel, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glShaderBinary, (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length), (n, shaders, binaryformat, binary, length), 5, "GLsizei", n, "const GLuint*", shaders, "GLenum", binaryformat, "const GLvoid*", binary, "GLsizei", length) +TRACE_GL_VOID(glShaderSource, (GLuint shader, GLsizei count, const GLchar** string, const GLint* length), (shader, count, string, length), 4, "GLuint", shader, "GLsizei", count, "const GLchar**", string, "const GLint*", length) +TRACE_GL_VOID(glStartTilingQCOM, (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask), (x, y, width, height, preserveMask), 5, "GLuint", x, "GLuint", y, "GLuint", width, "GLuint", height, "GLbitfield", preserveMask) +TRACE_GL_VOID(glStencilFunc, (GLenum func, GLint ref, GLuint mask), (func, ref, mask), 3, "GLenum", func, "GLint", ref, "GLuint", mask) +TRACE_GL_VOID(glStencilFuncSeparate, (GLenum face, GLenum func, GLint ref, GLuint mask), (face, func, ref, mask), 4, "GLenum", face, "GLenum", func, "GLint", ref, "GLuint", mask) +TRACE_GL_VOID(glStencilMask, (GLuint mask), (mask), 1, "GLuint", mask) +TRACE_GL_VOID(glStencilMaskSeparate, (GLenum face, GLuint mask), (face, mask), 2, "GLenum", face, "GLuint", mask) +TRACE_GL_VOID(glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass), (fail, zfail, zpass), 3, "GLenum", fail, "GLenum", zfail, "GLenum", zpass) +TRACE_GL_VOID(glStencilOpSeparate, (GLenum face, GLenum fail, GLenum zfail, GLenum zpass), (face, fail, zfail, zpass), 4, "GLenum", face, "GLenum", fail, "GLenum", zfail, "GLenum", zpass) +TRACE_GL(GLboolean, glTestFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL_VOID(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glTexEnvf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexEnvfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexEnvi, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexEnviv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexEnvx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexEnvxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexEnvxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexEnvxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexGenfOES, (GLenum coord, GLenum pname, GLfloat param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexGenfvOES, (GLenum coord, GLenum pname, const GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexGeniOES, (GLenum coord, GLenum pname, GLint param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexGenivOES, (GLenum coord, GLenum pname, const GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexGenxOES, (GLenum coord, GLenum pname, GLfixed param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexGenxvOES, (GLenum coord, GLenum pname, const GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels), (target, level, internalformat, width, height, border, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid *", pixels) +TRACE_GL_VOID(glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels), (target, level, internalformat, width, height, depth, border, format, type, pixels), 10, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid*", pixels) +TRACE_GL_VOID(glTexParameterf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexParameterfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexParameteri, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexParameteriv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexParameterx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexParameterxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), (target, level, xoffset, yoffset, width, height, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "const GLvoid *", pixels) +TRACE_GL_VOID(glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "const GLvoid*", pixels) +TRACE_GL_VOID(glTranslatef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glTranslatex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glUniform1f, (GLint location, GLfloat x), (location, x), 2, "GLint", location, "GLfloat", x) +TRACE_GL_VOID(glUniform1fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform1i, (GLint location, GLint x), (location, x), 2, "GLint", location, "GLint", x) +TRACE_GL_VOID(glUniform1iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform2f, (GLint location, GLfloat x, GLfloat y), (location, x, y), 3, "GLint", location, "GLfloat", x, "GLfloat", y) +TRACE_GL_VOID(glUniform2fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform2i, (GLint location, GLint x, GLint y), (location, x, y), 3, "GLint", location, "GLint", x, "GLint", y) +TRACE_GL_VOID(glUniform2iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform3f, (GLint location, GLfloat x, GLfloat y, GLfloat z), (location, x, y, z), 4, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glUniform3fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform3i, (GLint location, GLint x, GLint y, GLint z), (location, x, y, z), 4, "GLint", location, "GLint", x, "GLint", y, "GLint", z) +TRACE_GL_VOID(glUniform3iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform4f, (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (location, x, y, z, w), 5, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w) +TRACE_GL_VOID(glUniform4fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform4i, (GLint location, GLint x, GLint y, GLint z, GLint w), (location, x, y, z, w), 5, "GLint", location, "GLint", x, "GLint", y, "GLint", z, "GLint", w) +TRACE_GL_VOID(glUniform4iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniformMatrix2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL_VOID(glUniformMatrix3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL_VOID(glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL(GLboolean, glUnmapBufferOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glUseProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glValidateProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glVertexAttrib1f, (GLuint indx, GLfloat x), (indx, x), 2, "GLuint", indx, "GLfloat", x) +TRACE_GL_VOID(glVertexAttrib1fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib2f, (GLuint indx, GLfloat x, GLfloat y), (indx, x, y), 3, "GLuint", indx, "GLfloat", x, "GLfloat", y) +TRACE_GL_VOID(glVertexAttrib2fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib3f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z), (indx, x, y, z), 4, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glVertexAttrib3fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib4f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (indx, x, y, z, w), 5, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w) +TRACE_GL_VOID(glVertexAttrib4fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttribPointer, (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr), (indx, size, type, normalized, stride, ptr), 6, "GLuint", indx, "GLint", size, "GLenum", type, "GLboolean", normalized, "GLsizei", stride, "const GLvoid*", ptr) +TRACE_GL_VOID(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glViewport, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glWeightPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) diff --git a/opengl/tests/gl2_java/AndroidManifest.xml b/opengl/tests/gl2_java/AndroidManifest.xml index 585b63f..8bb6840 100644 --- a/opengl/tests/gl2_java/AndroidManifest.xml +++ b/opengl/tests/gl2_java/AndroidManifest.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2009, 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. -*/ +<!-- Copyright (C) 2009 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/opengl/tests/gl2_java/res/values/strings.xml b/opengl/tests/gl2_java/res/values/strings.xml index d718b1d..06bd23c 100644 --- a/opengl/tests/gl2_java/res/values/strings.xml +++ b/opengl/tests/gl2_java/res/values/strings.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2006, 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. -*/ +<!-- Copyright (C) 2006 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. --> <!-- This file contains resource definitions for displayed strings, allowing diff --git a/opengl/tests/gl2_jni/AndroidManifest.xml b/opengl/tests/gl2_jni/AndroidManifest.xml index a72a6a5..1827e5f 100644 --- a/opengl/tests/gl2_jni/AndroidManifest.xml +++ b/opengl/tests/gl2_jni/AndroidManifest.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2009, 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. -*/ +<!-- Copyright (C) 2009 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/opengl/tests/gl2_jni/res/values/strings.xml b/opengl/tests/gl2_jni/res/values/strings.xml index e3f7331..a29c74b 100644 --- a/opengl/tests/gl2_jni/res/values/strings.xml +++ b/opengl/tests/gl2_jni/res/values/strings.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2006, 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. -*/ +<!-- Copyright (C) 2006 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. --> <!-- This file contains resource definitions for displayed strings, allowing diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk new file mode 100644 index 0000000..6304700 --- /dev/null +++ b/opengl/tests/gl2_yuvtex/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl2_yuvtex.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui + +LOCAL_MODULE:= test-opengl-gl2_yuvtex + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp new file mode 100644 index 0000000..602ea1a --- /dev/null +++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2010 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +using namespace android; + +static void printGLString(const char *name, GLenum s) { + // fprintf(stderr, "printGLString %s, %d\n", name, s); + const char *v = (const char *) glGetString(s); + // int error = glGetError(); + // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, + // (unsigned int) v); + // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) + // fprintf(stderr, "GL %s = %s\n", name, v); + // else + // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); + fprintf(stderr, "GL %s = %s\n", name, v); +} + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +static const char gVertexShader[] = "attribute vec4 vPosition;\n" + "varying vec2 yuvTexCoords;\n" + "void main() {\n" + " yuvTexCoords = vPosition.xy + vec2(0.5, 0.5);\n" + " gl_Position = vPosition;\n" + "}\n"; + +static const char gFragmentShader[] = "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "uniform samplerExternalOES yuvTexSampler;\n" + "varying vec2 yuvTexCoords;\n" + "void main() {\n" + " gl_FragColor = texture2D(yuvTexSampler, yuvTexCoords);\n" + "}\n"; + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + fprintf(stderr, "Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + } else { + fprintf(stderr, "Guessing at GL_INFO_LOG_LENGTH size\n"); + char* buf = (char*) malloc(0x1000); + if (buf) { + glGetShaderInfoLog(shader, 0x1000, NULL, buf); + fprintf(stderr, "Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + } + glDeleteShader(shader); + shader = 0; + } + } + return shader; +} + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + checkGlError("glAttachShader"); + glAttachShader(program, pixelShader); + checkGlError("glAttachShader"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + fprintf(stderr, "Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} + +GLuint gProgram; +GLint gvPositionHandle; +GLint gYuvTexSamplerHandle; + +bool setupGraphics(int w, int h) { + gProgram = createProgram(gVertexShader, gFragmentShader); + if (!gProgram) { + return false; + } + gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); + checkGlError("glGetAttribLocation"); + fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n", + gvPositionHandle); + gYuvTexSamplerHandle = glGetUniformLocation(gProgram, "yuvTexSampler"); + checkGlError("glGetUniformLocation"); + fprintf(stderr, "glGetUniformLocation(\"yuvTexSampler\") = %d\n", + gYuvTexSamplerHandle); + + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +int align(int x, int a) { + return (x + (a-1)) & (~(a-1)); +} + +const int yuvTexWidth = 608; +const int yuvTexHeight = 480; +const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12; +const int yuvTexOffsetY = 0; +const int yuvTexStrideY = (yuvTexWidth + 0xf) & ~0xf; +const int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight; +const int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; +const int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2; +const int yuvTexStrideU = yuvTexStrideV; +const bool yuvTexSameUV = false; +static sp<GraphicBuffer> yuvTexBuffer; +static GLuint yuvTex; + +bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) { + int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1; + int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1; + yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat, + yuvTexUsage); + char* buf = NULL; + status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err); + return false; + } + for (int x = 0; x < yuvTexWidth; x++) { + for (int y = 0; y < yuvTexHeight; y++) { + int parityX = (x / blockWidth) & 1; + int parityY = (y / blockHeight) & 1; + unsigned char intensity = (parityX ^ parityY) ? 63 : 191; + buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; + if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) { + buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; + if (yuvTexSameUV) { + buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity; + } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) { + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity; + } + } + } + } + + err = yuvTexBuffer->unlock(); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err); + return false; + } + + EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer(); + EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + clientBuffer, 0); + checkEglError("eglCreateImageKHR"); + if (img == EGL_NO_IMAGE_KHR) { + return false; + } + + glGenTextures(1, &yuvTex); + checkGlError("glGenTextures"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img); + checkGlError("glEGLImageTargetTexture2DOES"); + + return true; +} + +const GLfloat gTriangleVertices[] = { + -0.5f, 0.5f, + -0.5f, -0.5f, + 0.5f, -0.5f, + 0.5f, 0.5f, +}; + +void renderFrame() { + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + checkGlError("glClearColor"); + glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + glUseProgram(gProgram); + checkGlError("glUseProgram"); + + glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); + checkGlError("glVertexAttribPointer"); + glEnableVertexAttribArray(gvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + + glUniform1i(gYuvTexSamplerHandle, 0); + checkGlError("glUniform1i"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + checkGlError("glDrawArrays"); +} + +void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + printf(" %s: ", names[j].name); + printf("%d (0x%x)", value, value); + } + } + printf("\n"); +} + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLSurface surface; + EGLint w, h; + + EGLDisplay dpy; + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface(); + returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 1; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + printf("Chose this configuration:\n"); + printEGLConfiguration(dpy, myConfig); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 1; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 1; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 1; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + fprintf(stderr, "Window dimensions: %d x %d\n", w, h); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + if(!setupYuvTexSurface(dpy, context)) { + fprintf(stderr, "Could not set up texture surface.\n"); + return 1; + } + + if(!setupGraphics(w, h)) { + fprintf(stderr, "Could not set up graphics.\n"); + return 1; + } + + for (;;) { + renderFrame(); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + } + + return 0; +} diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml index 64bd6bf..5d0ec96 100644 --- a/opengl/tests/gl_jni/AndroidManifest.xml +++ b/opengl/tests/gl_jni/AndroidManifest.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2009, 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. -*/ +<!-- Copyright (C) 2009 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml index 880f5c9..aee9fa0 100644 --- a/opengl/tests/gl_jni/res/values/strings.xml +++ b/opengl/tests/gl_jni/res/values/strings.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2006, 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. -*/ +<!-- Copyright (C) 2006 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. --> <!-- This file contains resource definitions for displayed strings, allowing diff --git a/opengl/tests/gl_perf/Android.mk b/opengl/tests/gl_perf/Android.mk new file mode 100644 index 0000000..37647ca --- /dev/null +++ b/opengl/tests/gl_perf/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl2_perf.cpp \ + filltest.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui + +LOCAL_MODULE:= test-opengl-gl2_perf + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl_perf/fill_common.cpp b/opengl/tests/gl_perf/fill_common.cpp new file mode 100644 index 0000000..a069f67 --- /dev/null +++ b/opengl/tests/gl_perf/fill_common.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2007 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. + */ + +#include "fragment_shaders.cpp" + +FILE * fOut = NULL; +void ptSwap(); + +static char gCurrentTestName[1024]; +static uint32_t gWidth = 0; +static uint32_t gHeight = 0; + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + LOGE("after %s() glError (0x%x)\n", op, error); + } +} + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + LOGE("Could not compile shader %d:\n%s\n", shaderType, buf); + free(buf); + } + glDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +enum { + A_POS, + A_COLOR, + A_TEX0, + A_TEX1 +}; + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + checkGlError("glAttachShader v"); + glAttachShader(program, pixelShader); + checkGlError("glAttachShader p"); + + glBindAttribLocation(program, A_POS, "a_pos"); + glBindAttribLocation(program, A_COLOR, "a_color"); + glBindAttribLocation(program, A_TEX0, "a_tex0"); + glBindAttribLocation(program, A_TEX1, "a_tex1"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + checkGlError("createProgram"); + glUseProgram(program); + return program; +} + +uint64_t getTime() { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); +} + +uint64_t gTime; +void startTimer() { + gTime = getTime(); +} + + +static void endTimer(int count) { + uint64_t t2 = getTime(); + double delta = ((double)(t2 - gTime)) / 1000000000; + double pixels = (gWidth * gHeight) * count; + double mpps = pixels / delta / 1000000; + double dc60 = ((double)count) / delta / 60; + + if (fOut) { + fprintf(fOut, "%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); + fflush(fOut); + } else { + printf("%s, %f, %f\n", gCurrentTestName, mpps, dc60); + } + LOGI("%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); +} + + +static const char gVertexShader[] = + "attribute vec4 a_pos;\n" + "attribute vec4 a_color;\n" + "attribute vec2 a_tex0;\n" + "attribute vec2 a_tex1;\n" + "varying vec4 v_color;\n" + "varying vec2 v_tex0;\n" + "varying vec2 v_tex1;\n" + "uniform vec2 u_texOff;\n" + + "void main() {\n" + " v_color = a_color;\n" + " v_tex0 = a_tex0;\n" + " v_tex1 = a_tex1;\n" + " v_tex0.x += u_texOff.x;\n" + " v_tex1.y += u_texOff.y;\n" + " gl_Position = a_pos;\n" + "}\n"; + +static void setupVA() { + static const float vtx[] = { + -1.0f,-1.0f, + 1.0f,-1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f }; + static const float color[] = { + 1.0f,0.0f,1.0f,1.0f, + 0.0f,0.0f,1.0f,1.0f, + 1.0f,1.0f,0.0f,1.0f, + 1.0f,1.0f,1.0f,1.0f }; + static const float tex0[] = { + 0.0f,0.0f, + 1.0f,0.0f, + 0.0f,1.0f, + 1.0f,1.0f }; + static const float tex1[] = { + 1.0f,0.0f, + 1.0f,1.0f, + 0.0f,1.0f, + 0.0f,0.0f }; + + glEnableVertexAttribArray(A_POS); + glEnableVertexAttribArray(A_COLOR); + glEnableVertexAttribArray(A_TEX0); + glEnableVertexAttribArray(A_TEX1); + + glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx); + glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color); + glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0); + glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1); +} + +static void randUniform(int pgm, const char *var) { + int loc = glGetUniformLocation(pgm, var); + if (loc >= 0) { + float x = ((float)rand()) / RAND_MAX; + float y = ((float)rand()) / RAND_MAX; + float z = ((float)rand()) / RAND_MAX; + float w = ((float)rand()) / RAND_MAX; + glUniform4f(loc, x, y, z, w); + } +} + +static void doLoop(bool warmup, int pgm, uint32_t passCount) { + if (warmup) { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + ptSwap(); + glFinish(); + return; + } + + startTimer(); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + for (uint32_t ct=0; ct < passCount; ct++) { + int loc = glGetUniformLocation(pgm, "u_texOff"); + glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount); + + randUniform(pgm, "u_color"); + randUniform(pgm, "u_0"); + randUniform(pgm, "u_1"); + randUniform(pgm, "u_2"); + randUniform(pgm, "u_3"); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + ptSwap(); + glFinish(); + endTimer(passCount); +} + + +static uint32_t rgb(uint32_t r, uint32_t g, uint32_t b) +{ + uint32_t ret = 0xff000000; + ret |= r & 0xff; + ret |= (g & 0xff) << 8; + ret |= (b & 0xff) << 16; + return ret; +} + +void genTextures() { + uint32_t *m = (uint32_t *)malloc(1024*1024*4); + for (int y=0; y < 1024; y++){ + for (int x=0; x < 1024; x++){ + m[y*1024 + x] = rgb(x, (((x+y) & 0xff) == 0x7f) * 0xff, y); + } + } + glBindTexture(GL_TEXTURE_2D, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + for (int y=0; y < 16; y++){ + for (int x=0; x < 16; x++){ + m[y*16 + x] = rgb(x << 4, (((x+y) & 0xf) == 0x7) * 0xff, y << 4); + } + } + glBindTexture(GL_TEXTURE_2D, 2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + free(m); +} + +static void doSingleTest(uint32_t pgmNum, int tex) { + const char *pgmTxt = gFragmentTests[pgmNum]->txt; + int pgm = createProgram(gVertexShader, pgmTxt); + if (!pgm) { + printf("error running test\n"); + return; + } + int loc = glGetUniformLocation(pgm, "u_tex0"); + if (loc >= 0) glUniform1i(loc, 0); + loc = glGetUniformLocation(pgm, "u_tex1"); + if (loc >= 0) glUniform1i(loc, 1); + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, tex); + glActiveTexture(GL_TEXTURE0); + + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_BLEND); + //sprintf(str2, "%i, %i, %i, %i, %i, 0", + //useVarColor, texCount, modulateFirstTex, extraMath, tex0); + //doLoop(true, pgm, w, h, str2); + //doLoop(false, pgm, w, h, str2); + + glEnable(GL_BLEND); + sprintf(gCurrentTestName, "%s, %i, %i, 1", gFragmentTests[pgmNum]->name, pgmNum, tex); + doLoop(true, pgm, 100); + doLoop(false, pgm, 100); +} + diff --git a/opengl/tests/gl_perf/filltest.cpp b/opengl/tests/gl_perf/filltest.cpp new file mode 100644 index 0000000..3f8faca --- /dev/null +++ b/opengl/tests/gl_perf/filltest.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> +#include <string.h> + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <utils/Timers.h> +#include <EGL/egl.h> +#include <utils/Log.h> + + +using namespace android; + + +#include "fill_common.cpp" + + +bool doTest(uint32_t w, uint32_t h) { + gWidth = w; + gHeight = h; + setupVA(); + genTextures(); + + printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n"); + + for (uint32_t num = 0; num < gFragmentTestCount; num++) { + doSingleTest(num, 2); + if (gFragmentTests[num]->texCount) { + doSingleTest(num, 1); + } + } + + exit(0); + return true; +} diff --git a/opengl/tests/gl_perf/fragment_shaders.cpp b/opengl/tests/gl_perf/fragment_shaders.cpp new file mode 100644 index 0000000..79d5ead --- /dev/null +++ b/opengl/tests/gl_perf/fragment_shaders.cpp @@ -0,0 +1,139 @@ + +typedef struct FragmentTestRec { + const char * name; + uint32_t texCount; + const char * txt; +} FragmentTest; + +static FragmentTest fpFill = { + "Solid color", 0, + + "precision mediump float;\n" + "uniform vec4 u_color;\n" + "void main() {\n" + " gl_FragColor = u_color;\n" + "}\n" +}; + +static FragmentTest fpGradient = { + "Solid gradient", 0, + + "precision mediump float;\n" + "varying lowp vec4 v_color;\n" + "void main() {\n" + " gl_FragColor = v_color;\n" + "}\n" +}; + +static FragmentTest fpCopyTex = { + "Texture copy", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " gl_FragColor = texture2D(u_tex0, v_tex0);\n" + "}\n" +}; + +static FragmentTest fpCopyTexGamma = { + "Texture copy with gamma", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " t.rgb = pow(t.rgb, vec3(1.4, 1.4, 1.4));\n" + " gl_FragColor = t;\n" + "}\n" +}; + +static FragmentTest fpTexSpec = { + "Texture spec", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " float simSpec = dot(gl_FragCoord.xyz, gl_FragCoord.xyz);\n" + " simSpec = pow(clamp(simSpec, 0.1, 1.0), 40.0);\n" + " gl_FragColor = t + vec4(simSpec, simSpec, simSpec, simSpec);\n" + "}\n" +}; + +static FragmentTest fpDepTex = { + "Dependent Lookup", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " t += texture2D(u_tex0, t.xy);\n" + " gl_FragColor = t;\n" + "}\n" +}; + +static FragmentTest fpModulateConstantTex = { + "Texture modulate constant", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "uniform vec4 u_color;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= u_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest fpModulateVaryingTex = { + "Texture modulate gradient", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "varying lowp vec4 v_color;\n" + "uniform sampler2D u_tex0;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= v_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest fpModulateVaryingConstantTex = { + "Texture modulate gradient constant", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "varying lowp vec4 v_color;\n" + "uniform sampler2D u_tex0;\n" + "uniform vec4 u_color;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= v_color;\n" + " c *= u_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest *gFragmentTests[] = { + &fpFill, + &fpGradient, + &fpCopyTex, + &fpCopyTexGamma, + &fpTexSpec, + &fpDepTex, + &fpModulateConstantTex, + &fpModulateVaryingTex, + &fpModulateVaryingConstantTex, + +}; + +static const size_t gFragmentTestCount = sizeof(gFragmentTests) / sizeof(gFragmentTests[0]); diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp new file mode 100644 index 0000000..9dfcf1c --- /dev/null +++ b/opengl/tests/gl_perf/gl2_perf.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2007 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> + +using namespace android; + + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +bool doTest(uint32_t w, uint32_t h); + +static EGLDisplay dpy; +static EGLSurface surface; + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLint w, h; + + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface();
+ returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 0; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 0; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 0; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 0; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + glViewport(0, 0, w, h); + + for (;;) { + doTest(w, h); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + } + + return 0; +} + +void ptSwap() { + eglSwapBuffers(dpy, surface); +} + diff --git a/opengl/tests/gl_perfapp/Android.mk b/opengl/tests/gl_perfapp/Android.mk new file mode 100644 index 0000000..dd75a74 --- /dev/null +++ b/opengl/tests/gl_perfapp/Android.mk @@ -0,0 +1,54 @@ +######################################################################### +# OpenGL ES Perf App +# This makefile builds both an activity and a shared library. +######################################################################### +ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := GLPerf + +LOCAL_JNI_SHARED_LIBRARIES := libglperf + +# Run on Eclair +LOCAL_SDK_VERSION := 7 + +include $(BUILD_PACKAGE) + +######################################################################### +# Build JNI Shared Library +######################################################################### + +LOCAL_PATH:= $(LOCAL_PATH)/jni + +include $(CLEAR_VARS) + +# Optional tag would mean it doesn't get installed by default +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -Werror + +LOCAL_SRC_FILES:= \ + gl_code.cpp + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libEGL \ + libGLESv2 + +LOCAL_MODULE := libglperf + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif # TARGET_SIMULATOR diff --git a/opengl/tests/gl_perfapp/AndroidManifest.xml b/opengl/tests/gl_perfapp/AndroidManifest.xml new file mode 100644 index 0000000..ee4bd98 --- /dev/null +++ b/opengl/tests/gl_perfapp/AndroidManifest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.glperf" + android:versionName="1.0.0" android:versionCode="10000" > + <uses-sdk android:targetSdkVersion="7" android:minSdkVersion="7" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <application + android:label="@string/glperf_activity"> + <activity android:name="GLPerfActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp new file mode 100644 index 0000000..f993371 --- /dev/null +++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp @@ -0,0 +1,103 @@ +// OpenGL ES 2.0 code + +#include <nativehelper/jni.h> +#define LOG_TAG "GLPerf gl_code.cpp" +#include <utils/Log.h> + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <utils/Timers.h> + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#include "../../gl_perf/fill_common.cpp" + + +////////////////////////// + +// Width and height of the screen + +uint32_t w; +uint32_t h; + +// The stateClock starts at zero and increments by 1 every time we draw a frame. It is used to control which phase of the test we are in. + +int stateClock; +const int doLoopStates = 2; +const int doSingleTestStates = 2; +bool done; + +// Saves the parameters of the test (so we can print them out when we finish the timing.) + + +int pgm; + +void ptSwap() { +} + +void doTest() { + uint32_t testNum = stateClock >> 2; + int texSize = ((stateClock >> 1) & 0x1) + 1; + + if (testNum >= gFragmentTestCount) { + LOGI("done\n"); + if (fOut) { + fclose(fOut); + fOut = NULL; + } + done = true; + return; + } + + // LOGI("doTest %d %d %d\n", texCount, extraMath, testSubState); + +// for (uint32_t num = 0; num < gFragmentTestCount; num++) { + doSingleTest(testNum, texSize); +} + +extern "C" { + JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj, jint width, jint height); + JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj); +}; + +JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj, jint width, jint height) +{ + gWidth = width; + gHeight = height; + if (!done) { + stateClock = 0; + done = false; + setupVA(); + genTextures(); + const char* fileName = "/sdcard/glperf.csv"; + if (fOut != NULL) { + LOGI("Closing partially written output.n"); + fclose(fOut); + fOut = NULL; + } + LOGI("Writing to: %s\n",fileName); + fOut = fopen(fileName, "w"); + if (fOut == NULL) { + LOGE("Could not open: %s\n", fileName); + } + + LOGI("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n"); + if (fOut) fprintf(fOut,"varColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\r\n"); + } +} + +JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj) +{ + if (! done) { + if (stateClock > 0 && ((stateClock & 1) == 0)) { + //endTimer(100); + } + doTest(); + stateClock++; + } else { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + } +} diff --git a/opengl/tests/gl_perfapp/res/values/strings.xml b/opengl/tests/gl_perfapp/res/values/strings.xml new file mode 100644 index 0000000..52cd961 --- /dev/null +++ b/opengl/tests/gl_perfapp/res/values/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2006 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. +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="glperf_activity">GLPerf</string> + +</resources> + diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java new file mode 100644 index 0000000..e3f3abf --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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.glperf; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class GLPerfActivity extends Activity { + + GLPerfView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + mView = new GLPerfView(getApplication()); + setContentView(mView); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java new file mode 100644 index 0000000..89a0e54 --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007 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.glperf; + +// Wrapper for native library + +public class GLPerfLib { + + static { + System.loadLibrary("glperf"); + } + + /** + * @param width the current view width + * @param height the current view height + */ + public static native void init(int width, int height); + public static native void step(); +} diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java new file mode 100644 index 0000000..4ce4a4d --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2009 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.glperf; +/* + * 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 android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class GLPerfView extends GLSurfaceView { + private static String TAG = "GLPerfView"; + + public GLPerfView(Context context) { + super(context); + init(false, 0, 0); + } + + public GLPerfView(Context context, boolean translucent, int depth, int stencil) { + super(context); + init(translucent, depth, stencil); + } + + private void init(boolean translucent, int depth, int stencil) { + setEGLContextFactory(new ContextFactory()); + setEGLConfigChooser( translucent ? + new ConfigChooser(8,8,8,8, depth, stencil) : + new ConfigChooser(5,6,5,0, depth, stencil)); + setRenderer(new Renderer()); + } + + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { + Log.w(TAG, "creating OpenGL ES 2.0 context"); + checkEglError("Before eglCreateContext", egl); + int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); + checkEglError("After eglCreateContext", egl); + return context; + } + + public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + egl.eglDestroyContext(display, context); + } + } + + private static void checkEglError(String prompt, EGL10 egl) { + int error; + while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { + Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); + } + } + + private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + + public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + int[] num_config = new int[1]; + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); + // printConfigs(egl, display, configs); + return chooseConfig(egl, display, configs); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + EGLConfig closestConfig = null; + int closestDistance = 1000; + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + if (d >= mDepthSize && s>= mStencilSize) { + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + int distance = Math.abs(r - mRedSize) + + Math.abs(g - mGreenSize) + + Math.abs(b - mBlueSize) + + Math.abs(a - mAlphaSize); + if (distance < closestDistance) { + closestDistance = distance; + closestConfig = config; + } + } + } + return closestConfig; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w(TAG, String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w(TAG, String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } + + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w(TAG, String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } + + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + private int[] mValue = new int[1]; + } + + private static class Renderer implements GLSurfaceView.Renderer { + public void onDrawFrame(GL10 gl) { + GLPerfLib.step(); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLPerfLib.init(width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + // Do nothing. + } + } +} + diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk new file mode 100644 index 0000000..a78db25 --- /dev/null +++ b/opengl/tests/gl_yuvtex/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl_yuvtex.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv1_CM \ + libui + +LOCAL_MODULE:= test-opengl-gl_yuvtex + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp new file mode 100644 index 0000000..fbe65f1 --- /dev/null +++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2010 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +using namespace android; + +static void printGLString(const char *name, GLenum s) { + // fprintf(stderr, "printGLString %s, %d\n", name, s); + const char *v = (const char *) glGetString(s); + // int error = glGetError(); + // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, + // (unsigned int) v); + // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) + // fprintf(stderr, "GL %s = %s\n", name, v); + // else + // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); + fprintf(stderr, "GL %s = %s\n", name, v); +} + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +bool setupGraphics(int w, int h) { + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +int align(int x, int a) { + return (x + (a-1)) & (~(a-1)); +} + +const int yuvTexWidth = 600; +const int yuvTexHeight = 480; +const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12; +const int yuvTexOffsetY = 0; +const int yuvTexStrideY = (yuvTexWidth + 0xf) & ~0xf; +const int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight; +const int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; +const int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2; +const int yuvTexStrideU = yuvTexStrideV; +const bool yuvTexSameUV = false; +static sp<GraphicBuffer> yuvTexBuffer; +static GLuint yuvTex; + +bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) { + int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1; + int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1; + yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat, + yuvTexUsage); + char* buf = NULL; + status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err); + return false; + } + for (int x = 0; x < yuvTexWidth; x++) { + for (int y = 0; y < yuvTexHeight; y++) { + int parityX = (x / blockWidth) & 1; + int parityY = (y / blockHeight) & 1; + unsigned char intensity = (parityX ^ parityY) ? 63 : 191; + buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; + if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) { + buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; + if (yuvTexSameUV) { + buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity; + } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) { + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity; + } + } + } + } + + err = yuvTexBuffer->unlock(); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err); + return false; + } + + EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer(); + EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + clientBuffer, 0); + checkEglError("eglCreateImageKHR"); + if (img == EGL_NO_IMAGE_KHR) { + return false; + } + + glGenTextures(1, &yuvTex); + checkGlError("glGenTextures"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img); + checkGlError("glEGLImageTargetTexture2DOES"); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + checkGlError("glTexParameteri"); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + checkGlError("glTexParameteri"); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGlError("glTexEnvx"); + + GLint crop[4] = { 0, 0, yuvTexWidth, yuvTexHeight }; + glTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_CROP_RECT_OES, crop); + checkGlError("glTexParameteriv"); + + return true; +} + +void renderFrame(int w, int h) { + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + checkGlError("glClearColor"); + glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEnable(GL_TEXTURE_EXTERNAL_OES); + checkGlError("glEnable"); + + glDrawTexiOES(0, 0, 0, w, h); + checkGlError("glDrawTexiOES"); +} + +void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + printf(" %s: ", names[j].name); + printf("%d (0x%x)", value, value); + } + } + printf("\n"); +} + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLSurface surface; + EGLint w, h; + + EGLDisplay dpy; + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface(); + returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 1; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + printf("Chose this configuration:\n"); + printEGLConfiguration(dpy, myConfig); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 1; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 1; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 1; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + fprintf(stderr, "Window dimensions: %d x %d\n", w, h); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + if(!setupYuvTexSurface(dpy, context)) { + fprintf(stderr, "Could not set up texture surface.\n"); + return 1; + } + + if(!setupGraphics(w, h)) { + fprintf(stderr, "Could not set up graphics.\n"); + return 1; + } + + for (;;) { + static int dir = -1; + + renderFrame(w, h); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + + if (w <= 10 || h <= 10) + { + dir = -dir; + } + + if (w >= 1300 || h >= 900) + { + dir = -dir; + } + + + w += dir; + h += dir; + } + + return 0; +} diff --git a/opengl/tests/gldual/AndroidManifest.xml b/opengl/tests/gldual/AndroidManifest.xml index 06f4c4d..a36f4f7 100644 --- a/opengl/tests/gldual/AndroidManifest.xml +++ b/opengl/tests/gldual/AndroidManifest.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2009, 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. -*/ +<!-- Copyright (C) 2009 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/opengl/tests/gldual/res/values/strings.xml b/opengl/tests/gldual/res/values/strings.xml index 4267dff..b1f535d 100644 --- a/opengl/tests/gldual/res/values/strings.xml +++ b/opengl/tests/gldual/res/values/strings.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2006, 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. -*/ +<!-- Copyright (C) 2006 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. --> <!-- This file contains resource definitions for displayed strings, allowing diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk new file mode 100644 index 0000000..6312970 --- /dev/null +++ b/opengl/tests/hwc/Android.mk @@ -0,0 +1,156 @@ +# Copyright (C) 2010 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := tests +LOCAL_MODULE:= libhwcTest +LOCAL_SRC_FILES:= hwcTestLib.cpp +LOCAL_C_INCLUDES += system/extras/tests/include \ + bionic \ + bionic/libstdc++/include \ + external/stlport/stlport \ + frameworks/base/opengl/tests \ + frameworks/base/opengl/tests/include \ + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport +LOCAL_STATIC_LIBRARIES += libglTest +LOCAL_PRELINK_MODULE := false + +include $(BUILD_STATIC_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= hwcStress.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui \ + libhardware \ + +LOCAL_STATIC_LIBRARIES := \ + libtestUtil \ + libglTest \ + libhwcTest \ + +LOCAL_C_INCLUDES += \ + system/extras/tests/include \ + hardware/libhardware/include \ + frameworks/base/opengl/tests \ + frameworks/base/opengl/tests/include \ + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +LOCAL_MODULE:= hwcStress +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_NATIVE_TEST) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= hwcRects.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui \ + libhardware \ + +LOCAL_STATIC_LIBRARIES := \ + libtestUtil \ + libglTest \ + libhwcTest \ + +LOCAL_C_INCLUDES += \ + system/extras/tests/include \ + hardware/libhardware/include \ + frameworks/base/opengl/tests \ + frameworks/base/opengl/tests/include \ + +LOCAL_MODULE:= hwcRects +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_NATIVE_TEST) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= hwcColorEquiv.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui \ + libhardware \ + +LOCAL_STATIC_LIBRARIES := \ + libtestUtil \ + libglTest \ + libhwcTest \ + +LOCAL_C_INCLUDES += \ + system/extras/tests/include \ + hardware/libhardware/include \ + frameworks/base/opengl/tests \ + frameworks/base/opengl/tests/include \ + +LOCAL_MODULE:= hwcColorEquiv +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_NATIVE_TEST) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= hwcCommit.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui \ + libhardware \ + +LOCAL_STATIC_LIBRARIES := \ + libtestUtil \ + libglTest \ + libhwcTest \ + +LOCAL_C_INCLUDES += \ + system/extras/tests/include \ + hardware/libhardware/include \ + frameworks/base/opengl/tests \ + frameworks/base/opengl/tests/include \ + +LOCAL_MODULE:= hwcCommit +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativebenchmark + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_NATIVE_TEST) diff --git a/opengl/tests/hwc/hwcColorEquiv.cpp b/opengl/tests/hwc/hwcColorEquiv.cpp new file mode 100644 index 0000000..1d03948 --- /dev/null +++ b/opengl/tests/hwc/hwcColorEquiv.cpp @@ -0,0 +1,438 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Hardware Composer Color Equivalence + * + * Synopsis + * hwc_colorequiv [options] eFmt + * + * options: + -v - verbose + * -s <0.##, 0.##, 0.##> - Start color (default: <0.0, 0.0, 0.0> + * -e <0.##, 0.##, 0.##> - Ending color (default: <1.0, 1.0, 1.0> + * -r fmt - reference graphic format + * -D #.## - End of test delay + * + * graphic formats: + * RGBA8888 (reference frame default) + * RGBX8888 + * RGB888 + * RGB565 + * BGRA8888 + * RGBA5551 + * RGBA4444 + * YV12 + * + * Description + * Renders a horizontal blend in two frames. The first frame is rendered + * in the upper third of the display and is called the reference frame. + * The second frame is displayed in the middle third and is called the + * equivalence frame. The primary purpose of this utility is to verify + * that the colors produced in the reference and equivalence frames are + * the same. The colors are the same when the colors are the same + * vertically between the reference and equivalence frames. + * + * By default the reference frame is rendered through the use of the + * RGBA8888 graphic format. The -r option can be used to specify a + * non-default reference frame graphic format. The graphic format of + * the equivalence frame is determined by a single required positional + * parameter. Intentionally there is no default for the graphic format + * of the equivalence frame. + * + * The horizontal blend in the reference frame is produced from a linear + * interpolation from a start color (default: <0.0, 0.0, 0.0> on the left + * side to an end color (default <1.0, 1.0, 1.0> on the right side. Where + * possible the equivalence frame is rendered with the equivalent color + * from the reference frame. A color of black is used in the equivalence + * frame for cases where an equivalent color does not exist. + */ + +#include <algorithm> +#include <assert.h> +#include <cerrno> +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <libgen.h> +#include <sched.h> +#include <sstream> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <vector> + +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#define LOG_TAG "hwcColorEquivTest" +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +#include "hwcTestLib.h" + +using namespace std; +using namespace android; + +// Defaults for command-line options +const bool defaultVerbose = false; +const ColorFract defaultStartColor(0.0, 0.0, 0.0); +const ColorFract defaultEndColor(1.0, 1.0, 1.0); +const char *defaultRefFormat = "RGBA8888"; +const float defaultEndDelay = 2.0; // Default delay after rendering graphics + +// Defines +#define MAXSTR 100 +#define MAXCMD 200 +#define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once + // it has been added + +#define CMD_STOP_FRAMEWORK "stop 2>&1" +#define CMD_START_FRAMEWORK "start 2>&1" + +// Macros +#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array +#define MEMCLR(addr, size) do { \ + memset((addr), 0, (size)); \ + } while (0) + +// Globals +static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +static hwc_composer_device_t *hwcDevice; +static EGLDisplay dpy; +static EGLSurface surface; +static EGLint width, height; + +// Functions prototypes +void init(void); +void printSyntax(const char *cmd); + +// Command-line option settings +static bool verbose = defaultVerbose; +static ColorFract startRefColor = defaultStartColor; +static ColorFract endRefColor = defaultEndColor; +static float endDelay = defaultEndDelay; +static const struct hwcTestGraphicFormat *refFormat + = hwcTestGraphicFormatLookup(defaultRefFormat); +static const struct hwcTestGraphicFormat *equivFormat; + +/* + * Main + * + * Performs the following high-level sequence of operations: + * + * 1. Command-line parsing + * + * 2. Stop framework + * + * 3. Initialization + * + * 4. Create Hardware Composer description of reference and equivalence frames + * + * 5. Have Hardware Composer render the reference and equivalence frames + * + * 6. Delay for amount of time given by endDelay + * + * 7. Start framework + */ +int +main(int argc, char *argv[]) +{ + int rv, opt; + bool error; + char *chptr; + unsigned int pass; + char cmd[MAXCMD]; + string str; + + testSetLogCatTag(LOG_TAG); + + assert(refFormat != NULL); + + testSetLogCatTag(LOG_TAG); + + // Parse command line arguments + while ((opt = getopt(argc, argv, "vs:e:r:D:?h")) != -1) { + switch (opt) { + case 'D': // End of test delay + // Delay between completion of final pass and restart + // of framework + endDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (endDelay < 0.0)) { + testPrintE("Invalid command-line specified end of test delay " + "of: %s", optarg); + exit(1); + } + break; + + case 's': // Starting reference color + str = optarg; + while (optind < argc) { + if (*argv[optind] == '-') { break; } + char endChar = (str.length() > 1) ? str[str.length() - 1] : 0; + if ((endChar == '>') || (endChar == ']')) { break; } + str += " " + string(argv[optind++]); + } + { + istringstream in(str); + startRefColor = hwcTestParseColor(in, error); + // Any parse error or characters not used by parser + if (error + || (((unsigned int) in.tellg() != in.str().length()) + && (in.tellg() != (streampos) -1))) { + testPrintE("Invalid command-line specified start " + "reference color of: %s", str.c_str()); + exit(2); + } + } + break; + + case 'e': // Ending reference color + str = optarg; + while (optind < argc) { + if (*argv[optind] == '-') { break; } + char endChar = (str.length() > 1) ? str[str.length() - 1] : 0; + if ((endChar == '>') || (endChar == ']')) { break; } + str += " " + string(argv[optind++]); + } + { + istringstream in(str); + endRefColor = hwcTestParseColor(in, error); + // Any parse error or characters not used by parser + if (error + || (((unsigned int) in.tellg() != in.str().length()) + && (in.tellg() != (streampos) -1))) { + testPrintE("Invalid command-line specified end " + "reference color of: %s", str.c_str()); + exit(3); + } + } + break; + + case 'r': // Reference graphic format + refFormat = hwcTestGraphicFormatLookup(optarg); + if (refFormat == NULL) { + testPrintE("Unkown command-line specified reference graphic " + "format of: %s", optarg); + printSyntax(basename(argv[0])); + exit(4); + } + break; + + case 'v': // Verbose + verbose = true; + break; + + case 'h': // Help + case '?': + default: + printSyntax(basename(argv[0])); + exit(((optopt == 0) || (optopt == '?')) ? 0 : 5); + } + } + + // Expect a single positional parameter, which specifies the + // equivalence graphic format. + if (argc != (optind + 1)) { + testPrintE("Expected a single command-line postional parameter"); + printSyntax(basename(argv[0])); + exit(6); + } + equivFormat = hwcTestGraphicFormatLookup(argv[optind]); + if (equivFormat == NULL) { + testPrintE("Unkown command-line specified equivalence graphic " + "format of: %s", argv[optind]); + printSyntax(basename(argv[0])); + exit(7); + } + + testPrintI("refFormat: %u %s", refFormat->format, refFormat->desc); + testPrintI("equivFormat: %u %s", equivFormat->format, equivFormat->desc); + testPrintI("startRefColor: %s", ((string) startRefColor).c_str()); + testPrintI("endRefColor: %s", ((string) endRefColor).c_str()); + testPrintI("endDelay: %f", endDelay); + + // Stop framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK); + exit(8); + } + testExecCmd(cmd); + testDelay(1.0); // TODO - needs means to query whether asynchronous stop + // framework operation has completed. For now, just wait + // a long time. + + init(); + + // Use the upper third of the display for the reference frame and + // the middle third for the equivalence frame. + unsigned int refHeight = height / 3; + unsigned int refPosY = 0; // Reference frame Y position + unsigned int refPosX = 0; // Reference frame X position + unsigned int refWidth = width - refPosX; + if ((refWidth & refFormat->wMod) != 0) { + refWidth += refFormat->wMod - (refWidth % refFormat->wMod); + } + unsigned int equivHeight = height / 3; + unsigned int equivPosY = refHeight; // Equivalence frame Y position + unsigned int equivPosX = 0; // Equivalence frame X position + unsigned int equivWidth = width - equivPosX; + if ((equivWidth & equivFormat->wMod) != 0) { + equivWidth += equivFormat->wMod - (equivWidth % equivFormat->wMod); + } + + // Create reference and equivalence graphic buffers + const unsigned int numFrames = 2; + sp<GraphicBuffer> refFrame; + refFrame = new GraphicBuffer(refWidth, refHeight, + refFormat->format, texUsage); + if ((rv = refFrame->initCheck()) != NO_ERROR) { + testPrintE("refFrame initCheck failed, rv: %i", rv); + testPrintE(" width %u height: %u format: %u %s", refWidth, refHeight, + refFormat->format, + hwcTestGraphicFormat2str(refFormat->format)); + exit(9); + } + testPrintI("refFrame width: %u height: %u format: %u %s", + refWidth, refHeight, refFormat->format, + hwcTestGraphicFormat2str(refFormat->format)); + + sp<GraphicBuffer> equivFrame; + equivFrame = new GraphicBuffer(equivWidth, equivHeight, + equivFormat->format, texUsage); + if ((rv = refFrame->initCheck()) != NO_ERROR) { + testPrintE("refFrame initCheck failed, rv: %i", rv); + testPrintE(" width %u height: %u format: %u %s", refWidth, refHeight, + refFormat->format, + hwcTestGraphicFormat2str(refFormat->format)); + exit(10); + } + testPrintI("equivFrame width: %u height: %u format: %u %s", + equivWidth, equivHeight, equivFormat->format, + hwcTestGraphicFormat2str(equivFormat->format)); + + // Fill the frames with a horizontal blend + hwcTestFillColorHBlend(refFrame.get(), refFormat->format, + startRefColor, endRefColor); + hwcTestFillColorHBlend(equivFrame.get(), refFormat->format, + startRefColor, endRefColor); + + hwc_layer_list_t *list; + size_t size = sizeof(hwc_layer_list) + numFrames * sizeof(hwc_layer_t); + if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) { + testPrintE("Allocate list failed"); + exit(11); + } + list->flags = HWC_GEOMETRY_CHANGED; + list->numHwLayers = numFrames; + + hwc_layer_t *layer = &list->hwLayers[0]; + layer->handle = refFrame->handle; + layer->blending = HWC_BLENDING_NONE; + layer->sourceCrop.left = 0; + layer->sourceCrop.top = 0; + layer->sourceCrop.right = width; + layer->sourceCrop.bottom = refHeight; + layer->displayFrame.left = 0; + layer->displayFrame.top = 0; + layer->displayFrame.right = width; + layer->displayFrame.bottom = refHeight; + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + + layer++; + layer->handle = equivFrame->handle; + layer->blending = HWC_BLENDING_NONE; + layer->sourceCrop.left = 0; + layer->sourceCrop.top = 0; + layer->sourceCrop.right = width; + layer->sourceCrop.bottom = equivHeight; + layer->displayFrame.left = 0; + layer->displayFrame.top = refHeight; + layer->displayFrame.right = width; + layer->displayFrame.bottom = layer->displayFrame.top + equivHeight; + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + + // Perform prepare operation + if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } + hwcDevice->prepare(hwcDevice, list); + if (verbose) { + testPrintI("Post Prepare:"); + hwcTestDisplayListPrepareModifiable(list); + } + + // Turn off the geometry changed flag + list->flags &= ~HWC_GEOMETRY_CHANGED; + + if (verbose) {hwcTestDisplayListHandles(list); } + hwcDevice->set(hwcDevice, dpy, surface, list); + + testDelay(endDelay); + + // Start framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_START_FRAMEWORK); + exit(12); + } + testExecCmd(cmd); + + return 0; +} + +void init(void) +{ + // Seed pseudo random number generator + // Seeding causes fill horizontal blend to fill the pad area with + // a deterministic set of values. + srand48(0); + + hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height); + + hwcTestOpenHwc(&hwcDevice); +} + +void printSyntax(const char *cmd) +{ + testPrintE(" %s [options] graphicFormat", cmd); + testPrintE(" options:"); + testPrintE(" -s <0.##, 0.##, 0.##> - Starting reference color"); + testPrintE(" -e <0.##, 0.##, 0.##> - Ending reference color"); + testPrintE(" -r format - Reference graphic format"); + testPrintE(" -D #.## - End of test delay"); + testPrintE(" -v Verbose"); + testPrintE(""); + testPrintE(" graphic formats:"); + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + testPrintE(" %s", hwcTestGraphicFormat[n1].desc); + } +} diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp new file mode 100644 index 0000000..66ccdae --- /dev/null +++ b/opengl/tests/hwc/hwcCommit.cpp @@ -0,0 +1,1562 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Hardware Composer Commit Points + * + * Synopsis + * hwcCommit [options] graphicFormat ... + * options: + * -s [width, height] - Starting dimension + * -v - Verbose + * + * graphic formats: + * RGBA8888 (reference frame default) + * RGBX8888 + * RGB888 + * RGB565 + * BGRA8888 + * RGBA5551 + * RGBA4444 + * YV12 + * + * Description + * The Hardware Composer (HWC) Commit test is a benchmark that + * discovers the points at which the HWC will commit to rendering an + * overlay(s). Before rendering a set of overlays, the HWC is shown + * the list through a prepare call. During the prepare call the HWC + * is able to examine the list and specify which overlays it is able + * to handle. The overlays that it can't handle are typically composited + * by a higher level (e.g. Surface Flinger) and then the original list + * plus a composit of what HWC passed on are provided back to the HWC + * for rendering. + * + * Once an implementation of the HWC has been shipped, a regression would + * likely occur if a latter implementation started passing on conditions + * that it used to commit to. The primary purpose of this benchmark + * is the automated discovery of the commit points, where an implementation + * is on the edge between committing and not committing. These are commonly + * referred to as commit points. Between implementations changes to the + * commit points are allowed, as long as they improve what the HWC commits + * to. Once an implementation of the HWC is shipped, the commit points are + * not allowed to regress in future implementations. + * + * This benchmark takes a sampling and then adjusts until it finds a + * commit point. It doesn't exhaustively check all possible conditions, + * which do to the number of combinations would be impossible. Instead + * it starts its search from a starting dimension, that can be changed + * via the -s option. The search is also bounded by a set of search + * limits, that are hard-coded into a structure of constants named + * searchLimits. Results that happen to reach a searchLimit are prefixed + * with >=, so that it is known that the value could possibly be larger. + * + * Measurements are made for each of the graphic formats specified as + * positional parameters on the command-line. If no graphic formats + * are specified on the command line, then by default measurements are + * made and reported for each of the known graphic format. + */ + +#include <algorithm> +#include <assert.h> +#include <cerrno> +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <iomanip> +#include <istream> +#include <libgen.h> +#include <list> +#include <sched.h> +#include <sstream> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <vector> + +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#define LOG_TAG "hwcCommitTest" +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +#include <glTestLib.h> +#include <hwc/hwcTestLib.h> + +using namespace std; +using namespace android; + +// Defaults +const HwcTestDim defaultStartDim = HwcTestDim(100, 100); +const bool defaultVerbose = false; + +const uint32_t defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888; +const int32_t defaultTransform = 0; +const uint32_t defaultBlend = HWC_BLENDING_NONE; +const ColorFract defaultColor(0.5, 0.5, 0.5); +const float defaultAlpha = 1.0; // Opaque +const HwcTestDim defaultSourceDim(1, 1); +const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1}; +const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100}; + +// Global Constants +const uint32_t printFieldWidth = 2; +const struct searchLimits { + uint32_t numOverlays; + HwcTestDim sourceCrop; +} searchLimits = { + 10, + HwcTestDim(3000, 2000), +}; +const struct transformType { + const char *desc; + uint32_t id; +} transformType[] = { + {"fliph", HWC_TRANSFORM_FLIP_H}, + {"flipv", HWC_TRANSFORM_FLIP_V}, + {"rot90", HWC_TRANSFORM_ROT_90}, + {"rot180", HWC_TRANSFORM_ROT_180}, + {"rot270", HWC_TRANSFORM_ROT_270}, +}; +const struct blendType { + const char *desc; + uint32_t id; +} blendType[] = { + {"none", HWC_BLENDING_NONE}, + {"premult", HWC_BLENDING_PREMULT}, + {"coverage", HWC_BLENDING_COVERAGE}, +}; + +// Defines +#define MAXCMD 200 +#define CMD_STOP_FRAMEWORK "stop 2>&1" +#define CMD_START_FRAMEWORK "start 2>&1" + +// Macros +#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array + +// Local types +class Rectangle { +public: + Rectangle(uint32_t graphicFormat = defaultFormat, + HwcTestDim dfDim = HwcTestDim(1, 1), + HwcTestDim sDim = HwcTestDim(1, 1)); + void setSourceDim(HwcTestDim dim); + + uint32_t format; + uint32_t transform; + int32_t blend; + ColorFract color; + float alpha; + HwcTestDim sourceDim; + struct hwc_rect sourceCrop; + struct hwc_rect displayFrame; +}; + +class Range { +public: + Range(void) : _l(0), _u(0) {} + Range(uint32_t lower, uint32_t upper) : _l(lower), _u(upper) {} + uint32_t lower(void) { return _l; } + uint32_t upper(void) { return _u; } + + operator string(); + +private: + uint32_t _l; // lower + uint32_t _u; // upper +}; + +Range::operator string() +{ + ostringstream out; + + out << '[' << _l << ", " << _u << ']'; + + return out.str(); +} + +class Rational { +public: + Rational(void) : _n(0), _d(1) {} + Rational(uint32_t n, uint32_t d) : _n(n), _d(d) {} + uint32_t numerator(void) { return _n; } + uint32_t denominator(void) { return _d; } + void setNumerator(uint32_t numerator) { _n = numerator; } + + bool operator==(const Rational& other) const; + bool operator!=(const Rational& other) const { return !(*this == other); } + bool operator<(const Rational& other) const; + bool operator>(const Rational& other) const { + return (!(*this == other) && !(*this < other)); + } + static void double2Rational(double f, Range nRange, Range dRange, + Rational& lower, Rational& upper); + + operator string() const; + operator double() const { return (double) _n / (double) _d; } + + +private: + uint32_t _n; + uint32_t _d; +}; + +// Globals +static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +static hwc_composer_device_t *hwcDevice; +static EGLDisplay dpy; +static EGLSurface surface; +static EGLint width, height; +static size_t maxHeadingLen; +static vector<string> formats; + +// Measurements +struct meas { + uint32_t format; + uint32_t startDimOverlays; + uint32_t maxNonOverlapping; + uint32_t maxOverlapping; + list<uint32_t> transforms; + list<uint32_t> blends; + struct displayFrame { + uint32_t minWidth; + uint32_t minHeight; + HwcTestDim minDim; + uint32_t maxWidth; + uint32_t maxHeight; + HwcTestDim maxDim; + } df; + struct sourceCrop { + uint32_t minWidth; + uint32_t minHeight; + HwcTestDim minDim; + uint32_t maxWidth; + uint32_t maxHeight; + HwcTestDim maxDim; + Rational hScale; + HwcTestDim hScaleBestDf; + HwcTestDim hScaleBestSc; + Rational vScale; + HwcTestDim vScaleBestDf; + HwcTestDim vScaleBestSc; + } sc; + vector<uint32_t> overlapBlendNone; + vector<uint32_t> overlapBlendPremult; + vector<uint32_t> overlapBlendCoverage; +}; +vector<meas> measurements; + +// Function prototypes +uint32_t numOverlays(list<Rectangle>& rectList); +uint32_t maxOverlays(uint32_t format, bool allowOverlap); +list<uint32_t> supportedTransforms(uint32_t format); +list<uint32_t> supportedBlends(uint32_t format); +uint32_t dfMinWidth(uint32_t format); +uint32_t dfMinHeight(uint32_t format); +uint32_t dfMaxWidth(uint32_t format); +uint32_t dfMaxHeight(uint32_t format); +HwcTestDim dfMinDim(uint32_t format); +HwcTestDim dfMaxDim(uint32_t format); +uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim); +uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim); +uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim); +uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim); +HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim); +HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim); +Rational scHScale(uint32_t format, + const HwcTestDim& dfMin, const HwcTestDim& dfMax, + const HwcTestDim& scMin, const HwcTestDim& scMax, + HwcTestDim& outBestDf, HwcTestDim& outBestSc); +Rational scVScale(uint32_t format, + const HwcTestDim& dfMin, const HwcTestDim& dfMax, + const HwcTestDim& scMin, const HwcTestDim& scMax, + HwcTestDim& outBestDf, HwcTestDim& outBestSc); +uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat, + uint32_t backgroundBlend, uint32_t foregroundBlend); +string transformList2str(const list<uint32_t>& transformList); +string blendList2str(const list<uint32_t>& blendList); +void init(void); +void printFormatHeadings(size_t indent); +void printOverlapLine(size_t indent, const string formatStr, + const vector<uint32_t>& results); +void printSyntax(const char *cmd); + +// Command-line option settings +static bool verbose = defaultVerbose; +static HwcTestDim startDim = defaultStartDim; + +/* + * Main + * + * Performs the following high-level sequence of operations: + * + * 1. Command-line parsing + * + * 2. Form a list of command-line specified graphic formats. If + * no formats are specified, then form a list of all known formats. + * + * 3. Stop framework + * Only one user at a time is allowed to use the HWC. Surface + * Flinger uses the HWC and is part of the framework. Need to + * stop the framework so that Surface Flinger will stop using + * the HWC. + * + * 4. Initialization + * + * 5. For each graphic format in the previously formed list perform + * measurements on that format and report the results. + * + * 6. Start framework + */ +int +main(int argc, char *argv[]) +{ + int rv, opt; + char *chptr; + bool error; + string str; + char cmd[MAXCMD]; + list<Rectangle> rectList; + + testSetLogCatTag(LOG_TAG); + + // Parse command line arguments + while ((opt = getopt(argc, argv, "s:v?h")) != -1) { + switch (opt) { + + case 's': // Start Dimension + // Use arguments until next starts with a dash + // or current ends with a > or ] + str = optarg; + while (optind < argc) { + if (*argv[optind] == '-') { break; } + char endChar = (str.length() > 1) ? str[str.length() - 1] : 0; + if ((endChar == '>') || (endChar == ']')) { break; } + str += " " + string(argv[optind++]); + } + { + istringstream in(str); + startDim = hwcTestParseDim(in, error); + // Any parse error or characters not used by parser + if (error + || (((unsigned int) in.tellg() != in.str().length()) + && (in.tellg() != (streampos) -1))) { + testPrintE("Invalid command-line specified start " + "dimension of: %s", str.c_str()); + exit(8); + } + } + break; + + case 'v': // Verbose + verbose = true; + break; + + case 'h': // Help + case '?': + default: + printSyntax(basename(argv[0])); + exit(((optopt == 0) || (optopt == '?')) ? 0 : 11); + } + } + + // Positional parameters + // Positional parameters provide the names of graphic formats that + // measurements are to be made on. Measurements are made on all + // known graphic formats when no positional parameters are provided. + if (optind == argc) { + // No command-line specified graphic formats + // Add all graphic formats to the list of formats to be measured + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + formats.push_back(hwcTestGraphicFormat[n1].desc); + } + } else { + // Add names of command-line specified graphic formats to the + // list of formats to be tested + for (; argv[optind] != NULL; optind++) { + formats.push_back(argv[optind]); + } + } + + // Determine length of longest specified graphic format. + // This value is used for output formating + for (vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + maxHeadingLen = max(maxHeadingLen, it->length()); + } + + // Stop framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK); + exit(14); + } + testExecCmd(cmd); + testDelay(1.0); // TODO - needs means to query whether asynchronous stop + // framework operation has completed. For now, just wait + // a long time. + + testPrintI("startDim: %s", ((string) startDim).c_str()); + + init(); + + // For each of the graphic formats + for (vector<string>::iterator itFormat = formats.begin(); + itFormat != formats.end(); ++itFormat) { + + // Locate hwcTestLib structure that describes this format + const struct hwcTestGraphicFormat *format; + format = hwcTestGraphicFormatLookup((*itFormat).c_str()); + if (format == NULL) { + testPrintE("Unknown graphic format of: %s", (*itFormat).c_str()); + exit(1); + } + + // Display format header + testPrintI("format: %s", format->desc); + + // Create area to hold the measurements + struct meas meas; + struct meas *measPtr; + meas.format = format->format; + measurements.push_back(meas); + measPtr = &measurements[measurements.size() - 1]; + + // Start dimension num overlays + Rectangle rect(format->format, startDim); + rectList.clear(); + rectList.push_back(rect); + measPtr->startDimOverlays = numOverlays(rectList); + testPrintI(" startDimOverlays: %u", measPtr->startDimOverlays); + + // Skip the rest of the measurements, when the start dimension + // doesn't produce an overlay + if (measPtr->startDimOverlays == 0) { continue; } + + // Max Overlays + measPtr->maxNonOverlapping = maxOverlays(format->format, false); + testPrintI(" max nonOverlapping overlays: %s%u", + (measPtr->maxNonOverlapping == searchLimits.numOverlays) + ? ">= " : "", + measPtr->maxNonOverlapping); + measPtr->maxOverlapping = maxOverlays(format->format, true); + testPrintI(" max Overlapping overlays: %s%u", + (measPtr->maxOverlapping == searchLimits.numOverlays) + ? ">= " : "", + measPtr->maxOverlapping); + + // Transforms and blends + measPtr->transforms = supportedTransforms(format->format); + testPrintI(" transforms: %s", + transformList2str(measPtr->transforms).c_str()); + measPtr->blends = supportedBlends(format->format); + testPrintI(" blends: %s", + blendList2str(measPtr->blends).c_str()); + + // Display frame measurements + measPtr->df.minWidth = dfMinWidth(format->format); + testPrintI(" dfMinWidth: %u", measPtr->df.minWidth); + + measPtr->df.minHeight = dfMinHeight(format->format); + testPrintI(" dfMinHeight: %u", measPtr->df.minHeight); + + measPtr->df.maxWidth = dfMaxWidth(format->format); + testPrintI(" dfMaxWidth: %u", measPtr->df.maxWidth); + + measPtr->df.maxHeight = dfMaxHeight(format->format); + testPrintI(" dfMaxHeight: %u", measPtr->df.maxHeight); + + measPtr->df.minDim = dfMinDim(format->format); + testPrintI(" dfMinDim: %s", ((string) measPtr->df.minDim).c_str()); + + measPtr->df.maxDim = dfMaxDim(format->format); + testPrintI(" dfMaxDim: %s", ((string) measPtr->df.maxDim).c_str()); + + // Source crop measurements + measPtr->sc.minWidth = scMinWidth(format->format, measPtr->df.minDim); + testPrintI(" scMinWidth: %u", measPtr->sc.minWidth); + + measPtr->sc.minHeight = scMinHeight(format->format, measPtr->df.minDim); + testPrintI(" scMinHeight: %u", measPtr->sc.minHeight); + + measPtr->sc.maxWidth = scMaxWidth(format->format, measPtr->df.maxDim); + testPrintI(" scMaxWidth: %s%u", (measPtr->sc.maxWidth + == searchLimits.sourceCrop.width()) ? ">= " : "", + measPtr->sc.maxWidth); + + measPtr->sc.maxHeight = scMaxHeight(format->format, measPtr->df.maxDim); + testPrintI(" scMaxHeight: %s%u", (measPtr->sc.maxHeight + == searchLimits.sourceCrop.height()) ? ">= " : "", + measPtr->sc.maxHeight); + + measPtr->sc.minDim = scMinDim(format->format, measPtr->df.minDim); + testPrintI(" scMinDim: %s", ((string) measPtr->sc.minDim).c_str()); + + measPtr->sc.maxDim = scMaxDim(format->format, measPtr->df.maxDim); + testPrintI(" scMaxDim: %s%s", ((measPtr->sc.maxDim.width() + >= searchLimits.sourceCrop.width()) + || (measPtr->sc.maxDim.width() >= + searchLimits.sourceCrop.height())) ? ">= " : "", + ((string) measPtr->sc.maxDim).c_str()); + + measPtr->sc.hScale = scHScale(format->format, + measPtr->df.minDim, measPtr->df.maxDim, + measPtr->sc.minDim, measPtr->sc.maxDim, + measPtr->sc.hScaleBestDf, + measPtr->sc.hScaleBestSc); + testPrintI(" scHScale: %s%f", + (measPtr->sc.hScale + >= Rational(searchLimits.sourceCrop.width(), + measPtr->df.minDim.width())) ? ">= " : "", + (double) measPtr->sc.hScale); + testPrintI(" HScale Best Display Frame: %s", + ((string) measPtr->sc.hScaleBestDf).c_str()); + testPrintI(" HScale Best Source Crop: %s", + ((string) measPtr->sc.hScaleBestSc).c_str()); + + measPtr->sc.vScale = scVScale(format->format, + measPtr->df.minDim, measPtr->df.maxDim, + measPtr->sc.minDim, measPtr->sc.maxDim, + measPtr->sc.vScaleBestDf, + measPtr->sc.vScaleBestSc); + testPrintI(" scVScale: %s%f", + (measPtr->sc.vScale + >= Rational(searchLimits.sourceCrop.height(), + measPtr->df.minDim.height())) ? ">= " : "", + (double) measPtr->sc.vScale); + testPrintI(" VScale Best Display Frame: %s", + ((string) measPtr->sc.vScaleBestDf).c_str()); + testPrintI(" VScale Best Source Crop: %s", + ((string) measPtr->sc.vScaleBestSc).c_str()); + + // Overlap two graphic formats and different blends + // Results displayed after all overlap measurments with + // current format in the foreground + // TODO: make measurments with background blend other than + // none. All of these measurements are done with a + // background blend of HWC_BLENDING_NONE, with the + // blend type of the foregound being varied. + uint32_t foregroundFormat = format->format; + for (vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + uint32_t num; + + const struct hwcTestGraphicFormat *backgroundFormatPtr + = hwcTestGraphicFormatLookup((*it).c_str()); + uint32_t backgroundFormat = backgroundFormatPtr->format; + + num = numOverlapping(backgroundFormat, foregroundFormat, + HWC_BLENDING_NONE, HWC_BLENDING_NONE); + measPtr->overlapBlendNone.push_back(num); + + num = numOverlapping(backgroundFormat, foregroundFormat, + HWC_BLENDING_NONE, HWC_BLENDING_PREMULT); + measPtr->overlapBlendPremult.push_back(num); + + num = numOverlapping(backgroundFormat, foregroundFormat, + HWC_BLENDING_NONE, HWC_BLENDING_COVERAGE); + measPtr->overlapBlendCoverage.push_back(num); + } + + } + + // Display overlap results + size_t indent = 2; + testPrintI("overlapping blend: none"); + printFormatHeadings(indent); + for (vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + printOverlapLine(indent, *it, measurements[it + - formats.begin()].overlapBlendNone); + } + testPrintI(""); + + testPrintI("overlapping blend: premult"); + printFormatHeadings(indent); + for (vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + printOverlapLine(indent, *it, measurements[it + - formats.begin()].overlapBlendPremult); + } + testPrintI(""); + + testPrintI("overlapping blend: coverage"); + printFormatHeadings(indent); + for (vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + printOverlapLine(indent, *it, measurements[it + - formats.begin()].overlapBlendCoverage); + } + testPrintI(""); + + // Start framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_START_FRAMEWORK); + exit(21); + } + testExecCmd(cmd); + + return 0; +} + +// Determine the maximum number of overlays that are all of the same format +// that the HWC will commit to. If allowOverlap is true, then the rectangles +// are laid out on a diagonal starting from the upper left corner. With +// each rectangle adjust one pixel to the right and one pixel down. +// When allowOverlap is false, the rectangles are tiled in column major +// order. Note, column major ordering is used so that the initial rectangles +// are all on different horizontal scan rows. It is common that hardware +// has limits on the number of objects it can handle on any single row. +uint32_t maxOverlays(uint32_t format, bool allowOverlap) +{ + unsigned int max = 0; + + for (unsigned int numRects = 1; numRects <= searchLimits.numOverlays; + numRects++) { + list<Rectangle> rectList; + + for (unsigned int x = 0; + (x + startDim.width()) < (unsigned int) width; + x += (allowOverlap) ? 1 : startDim.width()) { + for (unsigned int y = 0; + (y + startDim.height()) < (unsigned int) height; + y += (allowOverlap) ? 1 : startDim.height()) { + Rectangle rect(format, startDim, startDim); + rect.displayFrame.left = x; + rect.displayFrame.top = y; + rect.displayFrame.right = x + startDim.width(); + rect.displayFrame.bottom = y + startDim.height(); + + rectList.push_back(rect); + + if (rectList.size() >= numRects) { break; } + } + if (rectList.size() >= numRects) { break; } + } + + uint32_t num = numOverlays(rectList); + if (num > max) { max = num; } + } + + return max; +} + +// Measures what transforms (i.e. flip horizontal, rotate 180) are +// supported by the specified format +list<uint32_t> supportedTransforms(uint32_t format) +{ + list<uint32_t> rv; + list<Rectangle> rectList; + Rectangle rect(format, startDim); + + // For each of the transform types + for (unsigned int idx = 0; idx < NUMA(transformType); idx++) { + unsigned int id = transformType[idx].id; + + rect.transform = id; + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + + if (num == 1) { + rv.push_back(id); + } + } + + return rv; +} + +// Determines which types of blends (i.e. none, premult, coverage) are +// supported by the specified format +list<uint32_t> supportedBlends(uint32_t format) +{ + list<uint32_t> rv; + list<Rectangle> rectList; + Rectangle rect(format, startDim); + + // For each of the blend types + for (unsigned int idx = 0; idx < NUMA(blendType); idx++) { + unsigned int id = blendType[idx].id; + + rect.blend = id; + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + + if (num == 1) { + rv.push_back(id); + } + } + + return rv; +} + +// Determines the minimum width of any display frame of the given format +// that the HWC will commit to. +uint32_t dfMinWidth(uint32_t format) +{ + uint32_t w; + list<Rectangle> rectList; + + for (w = 1; w <= startDim.width(); w++) { + HwcTestDim dim(w, startDim.height()); + Rectangle rect(format, dim); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return w; + } + } + if (w > startDim.width()) { + testPrintE("Failed to locate display frame min width"); + exit(33); + } + + return w; +} + +// Display frame minimum height +uint32_t dfMinHeight(uint32_t format) +{ + uint32_t h; + list<Rectangle> rectList; + + for (h = 1; h <= startDim.height(); h++) { + HwcTestDim dim(startDim.width(), h); + Rectangle rect(format, dim); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return h; + } + } + if (h > startDim.height()) { + testPrintE("Failed to locate display frame min height"); + exit(34); + } + + return h; +} + +// Display frame maximum width +uint32_t dfMaxWidth(uint32_t format) +{ + uint32_t w; + list<Rectangle> rectList; + + for (w = width; w >= startDim.width(); w--) { + HwcTestDim dim(w, startDim.height()); + Rectangle rect(format, dim); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return w; + } + } + if (w < startDim.width()) { + testPrintE("Failed to locate display frame max width"); + exit(35); + } + + return w; +} + +// Display frame maximum height +uint32_t dfMaxHeight(uint32_t format) +{ + uint32_t h; + + for (h = height; h >= startDim.height(); h--) { + HwcTestDim dim(startDim.width(), h); + Rectangle rect(format, dim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return h; + } + } + if (h < startDim.height()) { + testPrintE("Failed to locate display frame max height"); + exit(36); + } + + return h; +} + +// Determine the minimum number of pixels that the HWC will ever commit to. +// Note, this might be different that dfMinWidth * dfMinHeight, in that this +// function adjusts both the width and height from the starting dimension. +HwcTestDim dfMinDim(uint32_t format) +{ + uint64_t bestMinPixels = 0; + HwcTestDim bestDim; + bool bestSet = false; // True when value has been assigned to + // bestMinPixels and bestDim + + bool origVerbose = verbose; // Temporarily turn off verbose + verbose = false; + for (uint32_t w = 1; w <= startDim.width(); w++) { + for (uint32_t h = 1; h <= startDim.height(); h++) { + if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) { + break; + } + + HwcTestDim dim(w, h); + Rectangle rect(format, dim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + uint64_t pixels = dim.width() * dim.height(); + if (!bestSet || (pixels < bestMinPixels)) { + bestMinPixels = pixels; + bestDim = dim; + bestSet = true; + } + } + } + } + verbose = origVerbose; + + if (!bestSet) { + testPrintE("Unable to locate display frame min dimension"); + exit(20); + } + + return bestDim; +} + +// Display frame maximum dimension +HwcTestDim dfMaxDim(uint32_t format) +{ + uint64_t bestMaxPixels = 0; + HwcTestDim bestDim; + bool bestSet = false; // True when value has been assigned to + // bestMaxPixels and bestDim; + + // Potentially increase benchmark performance by first checking + // for the common case of supporting a full display frame. + HwcTestDim dim(width, height); + Rectangle rect(format, dim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num == 1) { return dim; } + + // TODO: Use a binary search + bool origVerbose = verbose; // Temporarily turn off verbose + verbose = false; + for (uint32_t w = startDim.width(); w <= (uint32_t) width; w++) { + for (uint32_t h = startDim.height(); h <= (uint32_t) height; h++) { + if (bestSet && ((w * h) <= bestMaxPixels)) { continue; } + + HwcTestDim dim(w, h); + Rectangle rect(format, dim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + uint64_t pixels = dim.width() * dim.height(); + if (!bestSet || (pixels > bestMaxPixels)) { + bestMaxPixels = pixels; + bestDim = dim; + bestSet = true; + } + } + } + } + verbose = origVerbose; + + if (!bestSet) { + testPrintE("Unable to locate display frame max dimension"); + exit(21); + } + + return bestDim; +} + +// Source crop minimum width +uint32_t scMinWidth(uint32_t format, const HwcTestDim& dfDim) +{ + uint32_t w; + list<Rectangle> rectList; + + // Source crop frame min width + for (w = 1; w <= dfDim.width(); w++) { + Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height())); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return w; + } + } + testPrintE("Failed to locate source crop min width"); + exit(35); +} + +// Source crop minimum height +uint32_t scMinHeight(uint32_t format, const HwcTestDim& dfDim) +{ + uint32_t h; + list<Rectangle> rectList; + + for (h = 1; h <= dfDim.height(); h++) { + Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h)); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return h; + } + } + testPrintE("Failed to locate source crop min height"); + exit(36); +} + +// Source crop maximum width +uint32_t scMaxWidth(uint32_t format, const HwcTestDim& dfDim) +{ + uint32_t w; + list<Rectangle> rectList; + + for (w = searchLimits.sourceCrop.width(); w >= dfDim.width(); w--) { + Rectangle rect(format, dfDim, HwcTestDim(w, dfDim.height())); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return w; + } + } + testPrintE("Failed to locate source crop max width"); + exit(35); +} + +// Source crop maximum height +uint32_t scMaxHeight(uint32_t format, const HwcTestDim& dfDim) +{ + uint32_t h; + list<Rectangle> rectList; + + for (h = searchLimits.sourceCrop.height(); h >= dfDim.height(); h--) { + Rectangle rect(format, dfDim, HwcTestDim(dfDim.width(), h)); + rectList.clear(); + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + return h; + } + } + testPrintE("Failed to locate source crop max height"); + exit(36); +} + +// Source crop minimum dimension +// Discovers the source crop with the least number of pixels that the +// HWC will commit to. Note, this may be different from scMinWidth +// * scMinHeight, in that this function searches for a combination of +// width and height. While the other routines always keep one of the +// dimensions equal to the corresponding start dimension. +HwcTestDim scMinDim(uint32_t format, const HwcTestDim& dfDim) +{ + uint64_t bestMinPixels = 0; + HwcTestDim bestDim; + bool bestSet = false; // True when value has been assigned to + // bestMinPixels and bestDim + + bool origVerbose = verbose; // Temporarily turn off verbose + verbose = false; + for (uint32_t w = 1; w <= dfDim.width(); w++) { + for (uint32_t h = 1; h <= dfDim.height(); h++) { + if (bestSet && ((w > bestMinPixels) || (h > bestMinPixels))) { + break; + } + + HwcTestDim dim(w, h); + Rectangle rect(format, dfDim, HwcTestDim(w, h)); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + uint64_t pixels = dim.width() * dim.height(); + if (!bestSet || (pixels < bestMinPixels)) { + bestMinPixels = pixels; + bestDim = dim; + bestSet = true; + } + } + } + } + verbose = origVerbose; + + if (!bestSet) { + testPrintE("Unable to locate source crop min dimension"); + exit(20); + } + + return bestDim; +} + +// Source crop maximum dimension +HwcTestDim scMaxDim(uint32_t format, const HwcTestDim& dfDim) +{ + uint64_t bestMaxPixels = 0; + HwcTestDim bestDim; + bool bestSet = false; // True when value has been assigned to + // bestMaxPixels and bestDim; + + // Potentially increase benchmark performance by first checking + // for the common case of supporting the maximum checked source size + HwcTestDim dim = searchLimits.sourceCrop; + Rectangle rect(format, dfDim, searchLimits.sourceCrop); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num == 1) { return dim; } + + // TODO: Use a binary search + bool origVerbose = verbose; // Temporarily turn off verbose + verbose = false; + for (uint32_t w = dfDim.width(); + w <= searchLimits.sourceCrop.width(); w++) { + for (uint32_t h = dfDim.height(); + h <= searchLimits.sourceCrop.height(); h++) { + if (bestSet && ((w * h) <= bestMaxPixels)) { continue; } + + HwcTestDim dim(w, h); + Rectangle rect(format, dfDim, dim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + if (num > 0) { + uint64_t pixels = dim.width() * dim.height(); + if (!bestSet || (pixels > bestMaxPixels)) { + bestMaxPixels = pixels; + bestDim = dim; + bestSet = true; + } + } + } + } + verbose = origVerbose; + + if (!bestSet) { + testPrintE("Unable to locate source crop max dimension"); + exit(21); + } + + return bestDim; +} + +// Source crop horizontal scale +// Determines the maximum factor by which the source crop can be larger +// that the display frame. The commit point is discovered through a +// binary search of rational numbers. The numerator in each of the +// rational numbers contains the dimension for the source crop, while +// the denominator specifies the dimension for the display frame. On +// each pass of the binary search the mid-point between the greatest +// point committed to (best) and the smallest point in which a commit +// has failed is calculated. This mid-point is then passed to a function +// named double2Rational, which determines the closest rational numbers +// just below and above the mid-point. By default the lower rational +// number is used for the scale factor on the next pass of the binary +// search. The upper value is only used when best is already equal +// to the lower value. This only occurs when the lower value has already +// been tried. +Rational scHScale(uint32_t format, + const HwcTestDim& dfMin, const HwcTestDim& dfMax, + const HwcTestDim& scMin, const HwcTestDim& scMax, + HwcTestDim& outBestDf, HwcTestDim& outBestSc) +{ + HwcTestDim scDim, dfDim; // Source crop and display frame dimension + Rational best(0, 1), minBad; // Current bounds for a binary search + // MinGood is set below the lowest + // possible scale. The value of minBad, + // will be set by the first pass + // of the binary search. + + // Perform the passes of the binary search + bool firstPass = true; + do { + // On first pass try the maximum scale within the search limits + if (firstPass) { + // Try the maximum possible scale, within the search limits + scDim = HwcTestDim(searchLimits.sourceCrop.width(), scMin.height()); + dfDim = dfMin; + } else { + // Subsequent pass + // Halve the difference between best and minBad. + Rational lower, upper, selected; + + // Try the closest ratio halfway between minBood and minBad; + // TODO: Avoid rounding issue by using Rational type for + // midpoint. For now will use double, which should + // have more than sufficient resolution. + double mid = (double) best + + ((double) minBad - (double) best) / 2.0; + Rational::double2Rational(mid, + Range(scMin.width(), scMax.width()), + Range(dfMin.width(), dfMax.width()), + lower, upper); + if (((lower == best) && (upper == minBad))) { + return best; + } + + // Use lower value unless its already been tried + selected = (lower != best) ? lower : upper; + + // Assign the size of the source crop and display frame + // from the selected ratio of source crop to display frame. + scDim = HwcTestDim(selected.numerator(), scMin.height()); + dfDim = HwcTestDim(selected.denominator(), dfMin.height()); + } + + // See if the HWC will commit to this combination + Rectangle rect(format, dfDim, scDim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + + if (verbose) { + testPrintI(" scHscale num: %u scale: %f dfDim: %s scDim: %s", + num, (float) Rational(scDim.width(), dfDim.width()), + ((string) dfDim).c_str(), ((string) scDim).c_str()); + } + if (num == 1) { + // HWC committed to the combination + // This is the best scale factor seen so far. Report the + // dimensions to the caller, in case nothing better is seen. + outBestDf = dfDim; + outBestSc = scDim; + + // Success on the first pass means the largest possible scale + // is supported, in which case no need to search any further. + if (firstPass) { return Rational(scDim.width(), dfDim.width()); } + + // Update the lower bound of the binary search + best = Rational(scDim.width(), dfDim.width()); + } else { + // HWC didn't commit to this combination, so update the + // upper bound of the binary search. + minBad = Rational(scDim.width(), dfDim.width()); + } + + firstPass = false; + } while (best != minBad); + + return best; +} + +// Source crop vertical scale +// Determines the maximum factor by which the source crop can be larger +// that the display frame. The commit point is discovered through a +// binary search of rational numbers. The numerator in each of the +// rational numbers contains the dimension for the source crop, while +// the denominator specifies the dimension for the display frame. On +// each pass of the binary search the mid-point between the greatest +// point committed to (best) and the smallest point in which a commit +// has failed is calculated. This mid-point is then passed to a function +// named double2Rational, which determines the closest rational numbers +// just below and above the mid-point. By default the lower rational +// number is used for the scale factor on the next pass of the binary +// search. The upper value is only used when best is already equal +// to the lower value. This only occurs when the lower value has already +// been tried. +Rational scVScale(uint32_t format, + const HwcTestDim& dfMin, const HwcTestDim& dfMax, + const HwcTestDim& scMin, const HwcTestDim& scMax, + HwcTestDim& outBestDf, HwcTestDim& outBestSc) +{ + HwcTestDim scDim, dfDim; // Source crop and display frame dimension + Rational best(0, 1), minBad; // Current bounds for a binary search + // MinGood is set below the lowest + // possible scale. The value of minBad, + // will be set by the first pass + // of the binary search. + + // Perform the passes of the binary search + bool firstPass = true; + do { + // On first pass try the maximum scale within the search limits + if (firstPass) { + // Try the maximum possible scale, within the search limits + scDim = HwcTestDim(scMin.width(), searchLimits.sourceCrop.height()); + dfDim = dfMin; + } else { + // Subsequent pass + // Halve the difference between best and minBad. + Rational lower, upper, selected; + + // Try the closest ratio halfway between minBood and minBad; + // TODO: Avoid rounding issue by using Rational type for + // midpoint. For now will use double, which should + // have more than sufficient resolution. + double mid = (double) best + + ((double) minBad - (double) best) / 2.0; + Rational::double2Rational(mid, + Range(scMin.height(), scMax.height()), + Range(dfMin.height(), dfMax.height()), + lower, upper); + if (((lower == best) && (upper == minBad))) { + return best; + } + + // Use lower value unless its already been tried + selected = (lower != best) ? lower : upper; + + // Assign the size of the source crop and display frame + // from the selected ratio of source crop to display frame. + scDim = HwcTestDim(scMin.width(), selected.numerator()); + dfDim = HwcTestDim(dfMin.width(), selected.denominator()); + } + + // See if the HWC will commit to this combination + Rectangle rect(format, dfDim, scDim); + list<Rectangle> rectList; + rectList.push_back(rect); + uint32_t num = numOverlays(rectList); + + if (verbose) { + testPrintI(" scHscale num: %u scale: %f dfDim: %s scDim: %s", + num, (float) Rational(scDim.height(), dfDim.height()), + ((string) dfDim).c_str(), ((string) scDim).c_str()); + } + if (num == 1) { + // HWC committed to the combination + // This is the best scale factor seen so far. Report the + // dimensions to the caller, in case nothing better is seen. + outBestDf = dfDim; + outBestSc = scDim; + + // Success on the first pass means the largest possible scale + // is supported, in which case no need to search any further. + if (firstPass) { return Rational(scDim.height(), dfDim.height()); } + + // Update the lower bound of the binary search + best = Rational(scDim.height(), dfDim.height()); + } else { + // HWC didn't commit to this combination, so update the + // upper bound of the binary search. + minBad = Rational(scDim.height(), dfDim.height()); + } + + firstPass = false; + } while (best != minBad); + + return best; +} + +uint32_t numOverlapping(uint32_t backgroundFormat, uint32_t foregroundFormat, + uint32_t backgroundBlend, uint32_t foregroundBlend) +{ + list<Rectangle> rectList; + + Rectangle background(backgroundFormat, startDim, startDim); + background.blend = backgroundBlend; + rectList.push_back(background); + + // TODO: Handle cases where startDim is so small that adding 5 + // causes frames not to overlap. + // TODO: Handle cases where startDim is so large that adding 5 + // cause a portion or all of the foreground displayFrame + // to be off the display. + Rectangle foreground(foregroundFormat, startDim, startDim); + foreground.displayFrame.left += 5; + foreground.displayFrame.top += 5; + foreground.displayFrame.right += 5; + foreground.displayFrame.bottom += 5; + background.blend = foregroundBlend; + rectList.push_back(foreground); + + uint32_t num = numOverlays(rectList); + + return num; +} + +Rectangle::Rectangle(uint32_t graphicFormat, HwcTestDim dfDim, + HwcTestDim sDim) : + format(graphicFormat), transform(defaultTransform), + blend(defaultBlend), color(defaultColor), alpha(defaultAlpha), + sourceCrop(sDim), displayFrame(dfDim) +{ + // Set source dimension + // Can't use a base initializer, because the setting of format + // must be done before setting the sourceDimension. + setSourceDim(sDim); +} + +void Rectangle::setSourceDim(HwcTestDim dim) +{ + this->sourceDim = dim; + + const struct hwcTestGraphicFormat *attrib; + attrib = hwcTestGraphicFormatLookup(this->format); + if (attrib != NULL) { + if (sourceDim.width() % attrib->wMod) { + sourceDim.setWidth(sourceDim.width() + attrib->wMod + - (sourceDim.width() % attrib->wMod)); + } + if (sourceDim.height() % attrib->hMod) { + sourceDim.setHeight(sourceDim.height() + attrib->hMod + - (sourceDim.height() % attrib->hMod)); + } + } +} + +// Rational member functions +bool Rational::operator==(const Rational& other) const +{ + if (((uint64_t) _n * other._d) + == ((uint64_t) _d * other._n)) { return true; } + + return false; +} + +bool Rational::operator<(const Rational& other) const +{ + if (((uint64_t) _n * other._d) + < ((uint64_t) _d * other._n)) { return true; } + + return false; +} + +Rational::operator string() const +{ + ostringstream out; + + out << _n << '/' << _d; + + return out.str(); +} + +void Rational::double2Rational(double f, Range nRange, Range dRange, + Rational& lower, Rational& upper) +{ + Rational bestLower(nRange.lower(), dRange.upper()); + Rational bestUpper(nRange.upper(), dRange.lower()); + + // Search for a better solution + for (uint32_t d = dRange.lower(); d <= dRange.upper(); d++) { + Rational val(d * f, d); // Lower, because double to int cast truncates + + if ((val.numerator() < nRange.lower()) + || (val.numerator() > nRange.upper())) { continue; } + + if (((double) val > (double) bestLower) && ((double) val <= f)) { + bestLower = val; + } + + val.setNumerator(val.numerator() + 1); + if (val.numerator() > nRange.upper()) { continue; } + + if (((double) val < (double) bestUpper) && ((double) val >= f)) { + bestUpper = val; + } + } + + lower = bestLower; + upper = bestUpper; +} + +// Local functions + +// Num Overlays +// Given a list of rectangles, determine how many HWC will commit to render +uint32_t numOverlays(list<Rectangle>& rectList) +{ + hwc_layer_list_t *hwcList; + list<sp<GraphicBuffer> > buffers; + + hwcList = hwcTestCreateLayerList(rectList.size()); + if (hwcList == NULL) { + testPrintE("numOverlays create hwcList failed"); + exit(30); + } + + hwc_layer_t *layer = &hwcList->hwLayers[0]; + for (std::list<Rectangle>::iterator it = rectList.begin(); + it != rectList.end(); ++it, ++layer) { + // Allocate the texture for the source frame + // and push it onto the buffers list, so that it + // stays in scope until a return from this function. + sp<GraphicBuffer> texture; + texture = new GraphicBuffer(it->sourceDim.width(), + it->sourceDim.height(), + it->format, texUsage); + buffers.push_back(texture); + + layer->handle = texture->handle; + layer->blending = it->blend; + layer->transform = it->transform; + layer->sourceCrop = it->sourceCrop; + layer->displayFrame = it->displayFrame; + + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + } + + // Perform prepare operation + if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(hwcList); } + hwcDevice->prepare(hwcDevice, hwcList); + if (verbose) { + testPrintI("Post Prepare:"); + hwcTestDisplayListPrepareModifiable(hwcList); + } + + // Count the number of overlays + uint32_t total = 0; + for (unsigned int n1 = 0; n1 < hwcList->numHwLayers; n1++) { + if (hwcList->hwLayers[n1].compositionType == HWC_OVERLAY) { + total++; + } + } + + // Free the layer list and graphic buffers + hwcTestFreeLayerList(hwcList); + + return total; +} + +string transformList2str(const list<uint32_t>& transformList) +{ + ostringstream out; + + for (list<uint32_t>::const_iterator it = transformList.begin(); + it != transformList.end(); ++it) { + uint32_t id = *it; + + if (it != transformList.begin()) { + out << ", "; + } + out << id; + + for (unsigned int idx = 0; idx < NUMA(transformType); idx++) { + if (id == transformType[idx].id) { + out << " (" << transformType[idx].desc << ')'; + break; + } + } + } + + return out.str(); +} + +string blendList2str(const list<uint32_t>& blendList) +{ + ostringstream out; + + for (list<uint32_t>::const_iterator it = blendList.begin(); + it != blendList.end(); ++it) { + uint32_t id = *it; + + if (it != blendList.begin()) { + out << ", "; + } + out << id; + + for (unsigned int idx = 0; idx < NUMA(blendType); idx++) { + if (id == blendType[idx].id) { + out << " (" << blendType[idx].desc << ')'; + break; + } + } + } + + return out.str(); +} + +void init(void) +{ + srand48(0); + + hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height); + + hwcTestOpenHwc(&hwcDevice); +} + +void printFormatHeadings(size_t indent) +{ + for (size_t row = 0; row <= maxHeadingLen; row++) { + ostringstream line; + for(vector<string>::iterator it = formats.begin(); + it != formats.end(); ++it) { + if ((maxHeadingLen - row) <= it->length()) { + if (row != maxHeadingLen) { + char ch = (*it)[it->length() - (maxHeadingLen - row)]; + line << ' ' << setw(printFieldWidth) << ch; + } else { + line << ' ' << string(printFieldWidth, '-'); + } + } else { + line << ' ' << setw(printFieldWidth) << ""; + } + } + testPrintI("%*s%s", indent + maxHeadingLen, "", + line.str().c_str()); + } +} + +void printOverlapLine(size_t indent, const string formatStr, + const vector<uint32_t>& results) +{ + ostringstream line; + + line << setw(indent + maxHeadingLen - formatStr.length()) << ""; + + line << formatStr; + + for (vector<uint32_t>::const_iterator it = results.begin(); + it != results.end(); ++it) { + line << ' ' << setw(printFieldWidth) << *it; + } + + testPrintI("%s", line.str().c_str()); +} + +void printSyntax(const char *cmd) +{ + testPrintE(" %s [options] [graphicFormat] ...", + cmd); + testPrintE(" options:"); + testPrintE(" -s [width, height] - start dimension"); + testPrintE(" -v - Verbose"); + testPrintE(""); + testPrintE(" graphic formats:"); + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + testPrintE(" %s", hwcTestGraphicFormat[n1].desc); + } +} diff --git a/opengl/tests/hwc/hwcRects.cpp b/opengl/tests/hwc/hwcRects.cpp new file mode 100644 index 0000000..523e3de --- /dev/null +++ b/opengl/tests/hwc/hwcRects.cpp @@ -0,0 +1,577 @@ +/* + * Copyright (C) 2011 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. + */ + +/* + * Hardware Composer Rectangles + * + * Synopsis + * hwcRects [options] (graphicFormat displayFrame [attributes],)... + * options: + * -D #.## - End of test delay + * -v - Verbose + * + * graphic formats: + * RGBA8888 (reference frame default) + * RGBX8888 + * RGB888 + * RGB565 + * BGRA8888 + * RGBA5551 + * RGBA4444 + * YV12 + * + * displayFrame + * [left, top, right, bottom] + * + * attributes: + * transform: none | fliph | flipv | rot90 | rot180 | rot270 + * blend: none | premult | coverage + * color: [0.##, 0.##, 0.##] + * alpha: 0.## + * sourceDim: [width, height] + * sourceCrop: [left, top, right, bottom] + * + * Example: + * # White YV12 rectangle, with overlapping turquoise + * # RGBA8888 rectangle at 30%% (alpha: 0.7) transparency + * hwcRects -v -D 30.0 \ + * YV12 [50, 80, 200, 300] transform: none \ + * color: [1.0, 0.5, 0.5], \ + * RGBA8888 [100, 150, 300, 400] blend: coverage \ + * color: [0.251, 0.878, 0.816] alpha: 0.7 \ + * sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15] + * + * Description + * Constructs a Hardware Composer (HWC) list of frames from + * command-line specified parameters. Then sends it to the HWC + * be rendered. The intended purpose of this tool is as a means to + * reproduce and succinctly specify an observed HWC operation, with + * no need to modify/compile a program. + * + * The command-line syntax consists of a few standard command-line + * options and then a description of one or more frames. The frame + * descriptions are separated from one another via a comma. The + * beginning of a frame description requires the specification + * of the graphic format and then the display frame rectangle where + * the frame will be displayed. The display frame rectangle is + * specified as follows, with the right and bottom coordinates being + * exclusive values: + * + * [left, top, right, bottom] + * + * After these two required parameters each frame description can + * specify 1 or more optional attributes. The name of each optional + * attribute is preceded by a colon. The current implementation + * then requires white space after the colon and then the value of + * the attribute is specified. See the synopsis section above for + * a list of attributes and the format of their expected value. + */ + +#include <algorithm> +#include <assert.h> +#include <cerrno> +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <istream> +#include <libgen.h> +#include <list> +#include <sched.h> +#include <sstream> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#define LOG_TAG "hwcRectsTest" +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +#include <glTestLib.h> +#include <hwc/hwcTestLib.h> + +using namespace std; +using namespace android; + +// Defaults +const bool defaultVerbose = false; +const float defaultEndDelay = 2.0; // Default delay after rendering graphics + +const uint32_t defaultFormat = HAL_PIXEL_FORMAT_RGBA_8888; +const int32_t defaultTransform = 0; +const uint32_t defaultBlend = HWC_BLENDING_NONE; +const ColorFract defaultColor(0.5, 0.5, 0.5); +const float defaultAlpha = 1.0; // Opaque +const HwcTestDim defaultSourceDim(1, 1); +const struct hwc_rect defaultSourceCrop = {0, 0, 1, 1}; +const struct hwc_rect defaultDisplayFrame = {0, 0, 100, 100}; + +// Defines +#define MAXCMD 200 +#define CMD_STOP_FRAMEWORK "stop 2>&1" +#define CMD_START_FRAMEWORK "start 2>&1" + +// Macros +#define NUMA(a) (sizeof(a) / sizeof(a [0])) // Num elements in an array + +// Local types +class Rectangle { +public: + Rectangle() : format(defaultFormat), transform(defaultTransform), + blend(defaultBlend), color(defaultColor), + alpha(defaultAlpha), sourceDim(defaultSourceDim), + sourceCrop(defaultSourceCrop), + displayFrame(defaultDisplayFrame) {}; + + uint32_t format; + uint32_t transform; + int32_t blend; + ColorFract color; + float alpha; + HwcTestDim sourceDim; + struct hwc_rect sourceCrop; + struct hwc_rect displayFrame; + + sp<GraphicBuffer> texture; +}; + +// Globals +list<Rectangle> rectangle; +static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +static hwc_composer_device_t *hwcDevice; +static EGLDisplay dpy; +static EGLSurface surface; +static EGLint width, height; + +// Function prototypes +static Rectangle parseRect(string rectStr); +void init(void); +void printSyntax(const char *cmd); + +// Command-line option settings +static bool verbose = defaultVerbose; +static float endDelay = defaultEndDelay; + +/* + * Main + * + * Performs the following high-level sequence of operations: + * + * 1. Parse command-line options + * + * 2. Stop framework + * + * 3. Initialization + * + * 4. Parse frame descriptions + * + * 5. Create HWC list from frame descriptions + * + * 6. Have HWC render the list description of the frames + * + * 7. Delay for amount of time given by endDelay + * + * 8. Start framework + */ +int +main(int argc, char *argv[]) +{ + int rv, opt; + char *chptr; + bool error; + string str; + char cmd[MAXCMD]; + + testSetLogCatTag(LOG_TAG); + + // Parse command line arguments + while ((opt = getopt(argc, argv, "D:v?h")) != -1) { + switch (opt) { + case 'D': // End of test delay + endDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (endDelay < 0.0)) { + testPrintE("Invalid command-line specified end of test delay " + "of: %s", optarg); + exit(1); + } + break; + + case 'v': // Verbose + verbose = true; + break; + + case 'h': // Help + case '?': + default: + printSyntax(basename(argv[0])); + exit(((optopt == 0) || (optopt == '?')) ? 0 : 2); + } + } + + // Stop framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK); + exit(3); + } + testExecCmd(cmd); + testDelay(1.0); // TODO - needs means to query whether asyncronous stop + // framework operation has completed. For now, just wait + // a long time. + + init(); + + // Parse rectangle descriptions + int numOpen = 0; // Current number of unmatched <[ + string rectDesc(""); // String description of a single rectangle + while (optind < argc) { + string argNext = string(argv[optind++]); + + if (rectDesc.length()) { rectDesc += ' '; } + rectDesc += argNext; + + // Count number of opening <[ and matching >] + // At this point not worried about an opening character being + // matched by it's corresponding closing character. For example, + // "<1.0, 2.0]" is incorrect because the opening < should be matched + // with a closing >, instead of the closing ]. Such errors are + // detected when the actual value is parsed. + for (unsigned int n1 = 0; n1 < argNext.length(); n1++) { + switch(argNext[n1]) { + case '[': + case '<': + numOpen++; + break; + + case ']': + case '>': + numOpen--; + break; + } + + // Error anytime there is more closing then opening characters + if (numOpen < 0) { + testPrintI("Mismatched number of opening <[ with " + "closing >] in: %s", rectDesc.c_str()); + exit(4); + } + } + + // Description of a rectangle is complete when all opening + // <[ are closed with >] and the string ends with a comma or + // there are no more args. + if ((numOpen == 0) && rectDesc.length() + && ((rectDesc[rectDesc.length() - 1] == ',') + || (optind == argc))) { + // Remove trailing comma if it is present + if (rectDesc[rectDesc.length() - 1] == ',') { + rectDesc.erase(rectDesc.length() - 1); + } + + // Parse string description of rectangle + Rectangle rect = parseRect(rectDesc); + + // Add to the list of rectangles + rectangle.push_back(rect); + + // Prepare for description of another rectangle + rectDesc = string(""); + } + } + + // Create list of frames + hwc_layer_list_t *list; + list = hwcTestCreateLayerList(rectangle.size()); + if (list == NULL) { + testPrintE("hwcTestCreateLayerList failed"); + exit(5); + } + + hwc_layer_t *layer = &list->hwLayers[0]; + for (std::list<Rectangle>::iterator it = rectangle.begin(); + it != rectangle.end(); ++it, ++layer) { + layer->handle = it->texture->handle; + layer->blending = it->blend; + layer->transform = it->transform; + layer->sourceCrop = it->sourceCrop; + layer->displayFrame = it->displayFrame; + + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + } + + // Perform prepare operation + if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } + hwcDevice->prepare(hwcDevice, list); + if (verbose) { + testPrintI("Post Prepare:"); + hwcTestDisplayListPrepareModifiable(list); + } + + // Turn off the geometry changed flag + list->flags &= ~HWC_GEOMETRY_CHANGED; + + // Perform the set operation(s) + if (verbose) {testPrintI("Set:"); } + if (verbose) { hwcTestDisplayListHandles(list); } + hwcDevice->set(hwcDevice, dpy, surface, list); + + testDelay(endDelay); + + // Start framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_START_FRAMEWORK); + exit(6); + } + testExecCmd(cmd); + + return 0; +} + +// Parse string description of rectangle and add it to list of rectangles +// to be rendered. +static Rectangle parseRect(string rectStr) +{ + int rv; + string str; + bool error; + istringstream in(rectStr); + const struct hwcTestGraphicFormat *format; + Rectangle rect; + struct hwc_rect hwcRect; + + // Graphic Format + in >> str; + if (!in) { + testPrintE("Error parsing format from: %s", rectStr.c_str()); + exit(20); + } + format = hwcTestGraphicFormatLookup(str.c_str()); + if (format == NULL) { + testPrintE("Unknown graphic format in: %s", rectStr.c_str()); + exit(21); + } + rect.format = format->format; + + // Display Frame + rect.displayFrame = hwcTestParseHwcRect(in, error); + if (error) { + testPrintE("Invalid display frame in: %s", rectStr.c_str()); + exit(22); + } + + // Set default sourceDim and sourceCrop based on size of display frame. + // Default is source size equal to the size of the display frame, with + // the source crop being the entire size of the source frame. + rect.sourceDim = HwcTestDim(rect.displayFrame.right + - rect.displayFrame.left, + rect.displayFrame.bottom + - rect.displayFrame.top); + rect.sourceCrop.left = 0; + rect.sourceCrop.top = 0; + rect.sourceCrop.right = rect.sourceDim.width(); + rect.sourceCrop.bottom = rect.sourceDim.height(); + + // Optional settings + while ((in.tellg() < (streampos) in.str().length()) + && (in.tellg() != (streampos) -1)) { + string attrName; + + in >> attrName; + if (in.eof()) { break; } + if (!in) { + testPrintE("Error reading attribute name in: %s", + rectStr.c_str()); + exit(23); + } + + // Transform + if (attrName == "transform:") { // Transform + string str; + + in >> str; + if (str == "none") { + rect.transform = 0; + } else if (str == "fliph") { + rect.transform = HWC_TRANSFORM_FLIP_H; + } else if (str == "flipv") { + rect.transform = HWC_TRANSFORM_FLIP_V; + } else if (str == "rot90") { + rect.transform = HWC_TRANSFORM_ROT_90; + } else if (str == "rot180") { + rect.transform = HWC_TRANSFORM_ROT_180; + } else if (str == "rot270") { + rect.transform = HWC_TRANSFORM_ROT_270; + } else { + testPrintE("Unknown transform of \"%s\" in: %s", str.c_str(), + rectStr.c_str()); + exit(24); + } + } else if (attrName == "blend:") { // Blend + string str; + + in >> str; + if (str == string("none")) { + rect.blend = HWC_BLENDING_NONE; + } else if (str == "premult") { + rect.blend = HWC_BLENDING_PREMULT; + } else if (str == "coverage") { + rect.blend = HWC_BLENDING_COVERAGE; + } else { + testPrintE("Unknown blend of \"%s\" in: %s", str.c_str(), + rectStr.c_str()); + exit(25); + } + } else if (attrName == "color:") { // Color + rect.color = hwcTestParseColor(in, error); + if (error) { + testPrintE("Error parsing color in: %s", rectStr.c_str()); + exit(26); + } + } else if (attrName == "alpha:") { // Alpha + in >> rect.alpha; + if (!in) { + testPrintE("Error parsing value for alpha attribute in: %s", + rectStr.c_str()); + exit(27); + } + } else if (attrName == "sourceDim:") { // Source Dimension + rect.sourceDim = hwcTestParseDim(in, error); + if (error) { + testPrintE("Error parsing source dimenision in: %s", + rectStr.c_str()); + exit(28); + } + } else if (attrName == "sourceCrop:") { // Source Crop + rect.sourceCrop = hwcTestParseHwcRect(in, error); + if (error) { + testPrintE("Error parsing source crop in: %s", + rectStr.c_str()); + exit(29); + } + } else { // Unknown attribute + testPrintE("Unknown attribute of \"%s\" in: %s", attrName.c_str(), + rectStr.c_str()); + exit(30); + } + } + + // Validate + if (((uint32_t) rect.sourceCrop.left >= rect.sourceDim.width()) + || ((uint32_t) rect.sourceCrop.right > rect.sourceDim.width()) + || ((uint32_t) rect.sourceCrop.top >= rect.sourceDim.height()) + || ((uint32_t) rect.sourceCrop.bottom > rect.sourceDim.height())) { + testPrintE("Invalid source crop in: %s", rectStr.c_str()); + exit(31); + } + if ((rect.displayFrame.left >= width) + || (rect.displayFrame.right > width) + || (rect.displayFrame.top >= height) + || (rect.displayFrame.bottom > height)) { + testPrintE("Invalid display frame in: %s", rectStr.c_str()); + exit(32); + } + if ((rect.alpha < 0.0) || (rect.alpha > 1.0)) { + testPrintE("Invalid alpha in: %s", rectStr.c_str()); + exit(33); + } + + // Create source texture + rect.texture = new GraphicBuffer(rect.sourceDim.width(), + rect.sourceDim.height(), + rect.format, texUsage); + if ((rv = rect.texture->initCheck()) != NO_ERROR) { + testPrintE("source texture initCheck failed, rv: %i", rv); + testPrintE(" %s", rectStr.c_str()); + + } + + // Fill with uniform color + hwcTestFillColor(rect.texture.get(), rect.color, rect.alpha); + if (verbose) { + testPrintI(" buf: %p handle: %p format: %s width: %u height: %u " + "color: %s alpha: %f", + rect.texture.get(), rect.texture->handle, format->desc, + rect.sourceDim.width(), rect.sourceDim.height(), + string(rect.color).c_str(), rect.alpha); + } + + return rect; +} + +void init(void) +{ + // Seed pseudo random number generator + // Needed so that the pad areas of frames are filled with a deterministic + // pseudo random value. + srand48(0); + + hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height); + + hwcTestOpenHwc(&hwcDevice); +} + +void printSyntax(const char *cmd) +{ + testPrintE(" %s [options] (graphicFormat displayFrame [attributes],)...", + cmd); + testPrintE(" options:"); + testPrintE(" -D End of test delay"); + testPrintE(" -v Verbose"); + testPrintE(""); + testPrintE(" graphic formats:"); + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + testPrintE(" %s", hwcTestGraphicFormat[n1].desc); + } + testPrintE(""); + testPrintE(" displayFrame"); + testPrintE(" [left, top, right, bottom]"); + testPrintE(""); + testPrintE(" attributes:"); + testPrintE(" transform: none | fliph | flipv | rot90 | rot180 " + " | rot270"); + testPrintE(" blend: none | premult | coverage"); + testPrintE(" color: [0.##, 0.##, 0.##]"); + testPrintE(" alpha: 0.##"); + testPrintE(" sourceDim: [width, height]"); + testPrintE(" sourceCrop: [left, top, right, bottom]"); + testPrintE(""); + testPrintE(" Example:"); + testPrintE(" # White YV12 rectangle, with overlapping turquoise "); + testPrintE(" # RGBA8888 rectangle at 30%% (alpha: 0.7) transparency"); + testPrintE(" %s -v -D 30.0 \\", cmd); + testPrintE(" YV12 [50, 80, 200, 300] transform: none \\"); + testPrintE(" color: [1.0, 0.5, 0.5], \\"); + testPrintE(" RGBA8888 [100, 150, 300, 400] blend: coverage \\"); + testPrintE(" color: [0.251, 0.878, 0.816] alpha: 0.7 \\"); + testPrintE(" sourceDim: [50, 60] sourceCrop: [5, 8, 12, 15]"); +} diff --git a/opengl/tests/hwc/hwcStress.cpp b/opengl/tests/hwc/hwcStress.cpp new file mode 100644 index 0000000..1cefb4b --- /dev/null +++ b/opengl/tests/hwc/hwcStress.cpp @@ -0,0 +1,645 @@ +/* + * Copyright (C) 2010 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. + * + */ + +/* + * Hardware Composer stress test + * + * Performs a pseudo-random (prandom) sequence of operations to the + * Hardware Composer (HWC), for a specified number of passes or for + * a specified period of time. By default the period of time is FLT_MAX, + * so that the number of passes will take precedence. + * + * The passes are grouped together, where (pass / passesPerGroup) specifies + * which group a particular pass is in. This causes every passesPerGroup + * worth of sequential passes to be within the same group. Computationally + * intensive operations are performed just once at the beginning of a group + * of passes and then used by all the passes in that group. This is done + * so as to increase both the average and peak rate of graphic operations, + * by moving computationally intensive operations to the beginning of a group. + * In particular, at the start of each group of passes a set of + * graphic buffers are created, then used by the first and remaining + * passes of that group of passes. + * + * The per-group initialization of the graphic buffers is performed + * by a function called initFrames. This function creates an array + * of smart pointers to the graphic buffers, in the form of a vector + * of vectors. The array is accessed in row major order, so each + * row is a vector of smart pointers. All the pointers of a single + * row point to graphic buffers which use the same pixel format and + * have the same dimension, although it is likely that each one is + * filled with a different color. This is done so that after doing + * the first HWC prepare then set call, subsequent set calls can + * be made with each of the layer handles changed to a different + * graphic buffer within the same row. Since the graphic buffers + * in a particular row have the same pixel format and dimension, + * additional HWC set calls can be made, without having to perform + * an HWC prepare call. + * + * This test supports the following command-line options: + * + * -v Verbose + * -s num Starting pass + * -e num Ending pass + * -p num Execute the single pass specified by num + * -n num Number of set operations to perform after each prepare operation + * -t float Maximum time in seconds to execute the test + * -d float Delay in seconds performed after each set operation + * -D float Delay in seconds performed after the last pass is executed + * + * Typically the test is executed for a large range of passes. By default + * passes 0 through 99999 (100,000 passes) are executed. Although this test + * does not validate the generated image, at times it is useful to reexecute + * a particular pass and leave the displayed image on the screen for an + * extended period of time. This can be done either by setting the -s + * and -e options to the desired pass, along with a large value for -D. + * This can also be done via the -p option, again with a large value for + * the -D options. + * + * So far this test only contains code to create graphic buffers with + * a continuous solid color. Although this test is unable to validate the + * image produced, any image that contains other than rectangles of a solid + * color are incorrect. Note that the rectangles may use a transparent + * color and have a blending operation that causes the color in overlapping + * rectangles to be mixed. In such cases the overlapping portions may have + * a different color from the rest of the rectangle. + */ + +#include <algorithm> +#include <assert.h> +#include <cerrno> +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <libgen.h> +#include <sched.h> +#include <sstream> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <vector> + +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#define LOG_TAG "hwcStressTest" +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +#include <glTestLib.h> +#include <hwc/hwcTestLib.h> + +using namespace std; +using namespace android; + +const float maxSizeRatio = 1.3; // Graphic buffers can be upto this munch + // larger than the default screen size +const unsigned int passesPerGroup = 10; // A group of passes all use the same + // graphic buffers + +// Ratios at which rare and frequent conditions should be produced +const float rareRatio = 0.1; +const float freqRatio = 0.9; + +// Defaults for command-line options +const bool defaultVerbose = false; +const unsigned int defaultStartPass = 0; +const unsigned int defaultEndPass = 99999; +const unsigned int defaultPerPassNumSet = 10; +const float defaultPerSetDelay = 0.0; // Default delay after each set + // operation. Default delay of + // zero used so as to perform the + // the set operations as quickly + // as possible. +const float defaultEndDelay = 2.0; // Default delay between completion of + // final pass and restart of framework +const float defaultDuration = FLT_MAX; // A fairly long time, so that + // range of passes will have + // precedence + +// Command-line option settings +static bool verbose = defaultVerbose; +static unsigned int startPass = defaultStartPass; +static unsigned int endPass = defaultEndPass; +static unsigned int numSet = defaultPerPassNumSet; +static float perSetDelay = defaultPerSetDelay; +static float endDelay = defaultEndDelay; +static float duration = defaultDuration; + +// Command-line mutual exclusion detection flags. +// Corresponding flag set true once an option is used. +bool eFlag, sFlag, pFlag; + +#define MAXSTR 100 +#define MAXCMD 200 +#define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once + // it has been added + +#define CMD_STOP_FRAMEWORK "stop 2>&1" +#define CMD_START_FRAMEWORK "start 2>&1" + +#define NUMA(a) (sizeof(a) / sizeof(a [0])) +#define MEMCLR(addr, size) do { \ + memset((addr), 0, (size)); \ + } while (0) + +// File scope constants +const unsigned int blendingOps[] = { + HWC_BLENDING_NONE, + HWC_BLENDING_PREMULT, + HWC_BLENDING_COVERAGE, +}; +const unsigned int layerFlags[] = { + HWC_SKIP_LAYER, +}; +const vector<unsigned int> vecLayerFlags(layerFlags, + layerFlags + NUMA(layerFlags)); + +const unsigned int transformFlags[] = { + HWC_TRANSFORM_FLIP_H, + HWC_TRANSFORM_FLIP_V, + HWC_TRANSFORM_ROT_90, + // ROT_180 & ROT_270 intentionally not listed, because they + // they are formed from combinations of the flags already listed. +}; +const vector<unsigned int> vecTransformFlags(transformFlags, + transformFlags + NUMA(transformFlags)); + +// File scope globals +static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +static hwc_composer_device_t *hwcDevice; +static EGLDisplay dpy; +static EGLSurface surface; +static EGLint width, height; +static vector <vector <sp<GraphicBuffer> > > frames; + +// File scope prototypes +void init(void); +void initFrames(unsigned int seed); +template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num); +template <class T> T vectorOr(const vector<T>& vec); + +/* + * Main + * + * Performs the following high-level sequence of operations: + * + * 1. Command-line parsing + * + * 2. Initialization + * + * 3. For each pass: + * + * a. If pass is first pass or in a different group from the + * previous pass, initialize the array of graphic buffers. + * + * b. Create a HWC list with room to specify a prandomly + * selected number of layers. + * + * c. Select a subset of the rows from the graphic buffer array, + * such that there is a unique row to be used for each + * of the layers in the HWC list. + * + * d. Prandomly fill in the HWC list with handles + * selected from any of the columns of the selected row. + * + * e. Pass the populated list to the HWC prepare call. + * + * f. Pass the populated list to the HWC set call. + * + * g. If additional set calls are to be made, then for each + * additional set call, select a new set of handles and + * perform the set call. + */ +int +main(int argc, char *argv[]) +{ + int rv, opt; + char *chptr; + unsigned int pass; + char cmd[MAXCMD]; + struct timeval startTime, currentTime, delta; + + testSetLogCatTag(LOG_TAG); + + // Parse command line arguments + while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) { + switch (opt) { + case 'd': // Delay after each set operation + perSetDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (perSetDelay < 0.0)) { + testPrintE("Invalid command-line specified per pass delay of: " + "%s", optarg); + exit(1); + } + break; + + case 'D': // End of test delay + // Delay between completion of final pass and restart + // of framework + endDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (endDelay < 0.0)) { + testPrintE("Invalid command-line specified end of test delay " + "of: %s", optarg); + exit(2); + } + break; + + case 't': // Duration + duration = strtod(optarg, &chptr); + if ((*chptr != '\0') || (duration < 0.0)) { + testPrintE("Invalid command-line specified duration of: %s", + optarg); + exit(3); + } + break; + + case 'n': // Num set operations per pass + numSet = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified num set per pass " + "of: %s", optarg); + exit(4); + } + break; + + case 's': // Starting Pass + sFlag = true; + if (pFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(5); + } + startPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified starting pass " + "of: %s", optarg); + exit(6); + } + break; + + case 'e': // Ending Pass + eFlag = true; + if (pFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(7); + } + endPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified ending pass " + "of: %s", optarg); + exit(8); + } + break; + + case 'p': // Run a single specified pass + pFlag = true; + if (sFlag || eFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(9); + } + startPass = endPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified pass of: %s", + optarg); + exit(10); + } + break; + + case 'v': // Verbose + verbose = true; + break; + + case 'h': // Help + case '?': + default: + testPrintE(" %s [options]", basename(argv[0])); + testPrintE(" options:"); + testPrintE(" -p Execute specified pass"); + testPrintE(" -s Starting pass"); + testPrintE(" -e Ending pass"); + testPrintE(" -t Duration"); + testPrintE(" -d Delay after each set operation"); + testPrintE(" -D End of test delay"); + testPrintE(" -n Num set operations per pass"); + testPrintE(" -v Verbose"); + exit(((optopt == 0) || (optopt == '?')) ? 0 : 11); + } + } + if (endPass < startPass) { + testPrintE("Unexpected ending pass before starting pass"); + testPrintE(" startPass: %u endPass: %u", startPass, endPass); + exit(12); + } + if (argc != optind) { + testPrintE("Unexpected command-line postional argument"); + testPrintE(" %s [-s start_pass] [-e end_pass] [-t duration]", + basename(argv[0])); + exit(13); + } + testPrintI("duration: %g", duration); + testPrintI("startPass: %u", startPass); + testPrintI("endPass: %u", endPass); + testPrintI("numSet: %u", numSet); + + // Stop framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK); + exit(14); + } + testExecCmd(cmd); + testDelay(1.0); // TODO - need means to query whether asyncronous stop + // framework operation has completed. For now, just wait + // a long time. + + init(); + + // For each pass + gettimeofday(&startTime, NULL); + for (pass = startPass; pass <= endPass; pass++) { + // Stop if duration of work has already been performed + gettimeofday(¤tTime, NULL); + delta = tvDelta(&startTime, ¤tTime); + if (tv2double(&delta) > duration) { break; } + + // Regenerate a new set of test frames when this pass is + // either the first pass or is in a different group then + // the previous pass. A group of passes are passes that + // all have the same quotient when their pass number is + // divided by passesPerGroup. + if ((pass == startPass) + || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) { + initFrames(pass / passesPerGroup); + } + + testPrintI("==== Starting pass: %u", pass); + + // Cause deterministic sequence of prandom numbers to be + // generated for this pass. + srand48(pass); + + hwc_layer_list_t *list; + list = hwcTestCreateLayerList(testRandMod(frames.size()) + 1); + if (list == NULL) { + testPrintE("hwcTestCreateLayerList failed"); + exit(20); + } + + // Prandomly select a subset of frames to be used by this pass. + vector <vector <sp<GraphicBuffer> > > selectedFrames; + selectedFrames = vectorRandSelect(frames, list->numHwLayers); + + // Any transform tends to create a layer that the hardware + // composer is unable to support and thus has to leave for + // SurfaceFlinger. Place heavy bias on specifying no transforms. + bool noTransform = testRandFract() > rareRatio; + + for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { + unsigned int idx = testRandMod(selectedFrames[n1].size()); + sp<GraphicBuffer> gBuf = selectedFrames[n1][idx]; + hwc_layer_t *layer = &list->hwLayers[n1]; + layer->handle = gBuf->handle; + + layer->blending = blendingOps[testRandMod(NUMA(blendingOps))]; + layer->flags = (testRandFract() > rareRatio) ? 0 + : vectorOr(vectorRandSelect(vecLayerFlags, + testRandMod(vecLayerFlags.size() + 1))); + layer->transform = (noTransform || testRandFract() > rareRatio) ? 0 + : vectorOr(vectorRandSelect(vecTransformFlags, + testRandMod(vecTransformFlags.size() + 1))); + layer->sourceCrop.left = testRandMod(gBuf->getWidth()); + layer->sourceCrop.top = testRandMod(gBuf->getHeight()); + layer->sourceCrop.right = layer->sourceCrop.left + + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1; + layer->sourceCrop.bottom = layer->sourceCrop.top + + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1; + layer->displayFrame.left = testRandMod(width); + layer->displayFrame.top = testRandMod(height); + layer->displayFrame.right = layer->displayFrame.left + + testRandMod(width - layer->displayFrame.left) + 1; + layer->displayFrame.bottom = layer->displayFrame.top + + testRandMod(height - layer->displayFrame.top) + 1; + + // Increase the frequency that a scale factor of 1.0 from + // the sourceCrop to displayFrame occurs. This is the + // most common scale factor used by applications and would + // be rarely produced by this stress test without this + // logic. + if (testRandFract() <= freqRatio) { + // Only change to scale factor to 1.0 if both the + // width and height will fit. + int sourceWidth = layer->sourceCrop.right + - layer->sourceCrop.left; + int sourceHeight = layer->sourceCrop.bottom + - layer->sourceCrop.top; + if (((layer->displayFrame.left + sourceWidth) <= width) + && ((layer->displayFrame.top + sourceHeight) <= height)) { + layer->displayFrame.right = layer->displayFrame.left + + sourceWidth; + layer->displayFrame.bottom = layer->displayFrame.top + + sourceHeight; + } + } + + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + } + + // Perform prepare operation + if (verbose) { testPrintI("Prepare:"); hwcTestDisplayList(list); } + hwcDevice->prepare(hwcDevice, list); + if (verbose) { + testPrintI("Post Prepare:"); + hwcTestDisplayListPrepareModifiable(list); + } + + // Turn off the geometry changed flag + list->flags &= ~HWC_GEOMETRY_CHANGED; + + // Perform the set operation(s) + if (verbose) {testPrintI("Set:"); } + for (unsigned int n1 = 0; n1 < numSet; n1++) { + if (verbose) { hwcTestDisplayListHandles(list); } + hwcDevice->set(hwcDevice, dpy, surface, list); + + // Prandomly select a new set of handles + for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { + unsigned int idx = testRandMod(selectedFrames[n1].size()); + sp<GraphicBuffer> gBuf = selectedFrames[n1][idx]; + hwc_layer_t *layer = &list->hwLayers[n1]; + layer->handle = (native_handle_t *) gBuf->handle; + } + + testDelay(perSetDelay); + } + + hwcTestFreeLayerList(list); + testPrintI("==== Completed pass: %u", pass); + } + + testDelay(endDelay); + + // Start framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_START_FRAMEWORK); + exit(21); + } + testExecCmd(cmd); + + testPrintI("Successfully completed %u passes", pass - startPass); + + return 0; +} + +void init(void) +{ + srand48(0); // Defensively set pseudo random number generator. + // Should not need to set this, because a stress test + // sets the seed on each pass. Defensively set it here + // so that future code that uses pseudo random numbers + // before the first pass will be deterministic. + + hwcTestInitDisplay(verbose, &dpy, &surface, &width, &height); + + hwcTestOpenHwc(&hwcDevice); +} + +/* + * Initialize Frames + * + * Creates an array of graphic buffers, within the global variable + * named frames. The graphic buffers are contained within a vector of + * vectors. All the graphic buffers in a particular row are of the same + * format and dimension. Each graphic buffer is uniformly filled with a + * prandomly selected color. It is likely that each buffer, even + * in the same row, will be filled with a unique color. + */ +void initFrames(unsigned int seed) +{ + int rv; + const size_t maxRows = 5; + const size_t minCols = 2; // Need at least double buffering + const size_t maxCols = 4; // One more than triple buffering + + if (verbose) { testPrintI("initFrames seed: %u", seed); } + srand48(seed); + size_t rows = testRandMod(maxRows) + 1; + + frames.clear(); + frames.resize(rows); + + for (unsigned int row = 0; row < rows; row++) { + // All frames within a row have to have the same format and + // dimensions. Width and height need to be >= 1. + unsigned int formatIdx = testRandMod(NUMA(hwcTestGraphicFormat)); + const struct hwcTestGraphicFormat *formatPtr + = &hwcTestGraphicFormat[formatIdx]; + int format = formatPtr->format; + + // Pick width and height, which must be >= 1 and the size + // mod the wMod/hMod value must be equal to 0. + size_t w = (width * maxSizeRatio) * testRandFract(); + size_t h = (height * maxSizeRatio) * testRandFract(); + w = max(1u, w); + h = max(1u, h); + if ((w % formatPtr->wMod) != 0) { + w += formatPtr->wMod - (w % formatPtr->wMod); + } + if ((h % formatPtr->hMod) != 0) { + h += formatPtr->hMod - (h % formatPtr->hMod); + } + if (verbose) { + testPrintI(" frame %u width: %u height: %u format: %u %s", + row, w, h, format, hwcTestGraphicFormat2str(format)); + } + + size_t cols = testRandMod((maxCols + 1) - minCols) + minCols; + frames[row].resize(cols); + for (unsigned int col = 0; col < cols; col++) { + ColorFract color(testRandFract(), testRandFract(), testRandFract()); + float alpha = testRandFract(); + + frames[row][col] = new GraphicBuffer(w, h, format, texUsage); + if ((rv = frames[row][col]->initCheck()) != NO_ERROR) { + testPrintE("GraphicBuffer initCheck failed, rv: %i", rv); + testPrintE(" frame %u width: %u height: %u format: %u %s", + row, w, h, format, hwcTestGraphicFormat2str(format)); + exit(80); + } + + hwcTestFillColor(frames[row][col].get(), color, alpha); + if (verbose) { + testPrintI(" buf: %p handle: %p color: %s alpha: %f", + frames[row][col].get(), frames[row][col]->handle, + string(color).c_str(), alpha); + } + } + } +} + +/* + * Vector Random Select + * + * Prandomly selects and returns num elements from vec. + */ +template <class T> +vector<T> vectorRandSelect(const vector<T>& vec, size_t num) +{ + vector<T> rv = vec; + + while (rv.size() > num) { + rv.erase(rv.begin() + testRandMod(rv.size())); + } + + return rv; +} + +/* + * Vector Or + * + * Or's togethen the values of each element of vec and returns the result. + */ +template <class T> +T vectorOr(const vector<T>& vec) +{ + T rv = 0; + + for (size_t n1 = 0; n1 < vec.size(); n1++) { + rv |= vec[n1]; + } + + return rv; +} diff --git a/opengl/tests/hwc/hwcTestLib.cpp b/opengl/tests/hwc/hwcTestLib.cpp new file mode 100644 index 0000000..925405e --- /dev/null +++ b/opengl/tests/hwc/hwcTestLib.cpp @@ -0,0 +1,1028 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Hardware Composer Test Library + * Utility library functions for use by the Hardware Composer test cases + */ + +#include <sstream> +#include <string> + +#include <arpa/inet.h> // For ntohl() and htonl() + +#include <hwc/hwcTestLib.h> + +// Defines +#define NUMA(a) (sizeof(a) / sizeof(a [0])) + +// Function Prototypes +static void printGLString(const char *name, GLenum s); +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE); +static void checkGlError(const char* op); +static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config); + +using namespace std; +using namespace android; + + +#define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once + // it has been added + +// Initialize Display +void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface, + EGLint *width, EGLint *height) +{ + static EGLContext context; + + int rv; + + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint sConfigAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion, minorVersion; + + checkEglError("<init>"); + *dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (*dpy == EGL_NO_DISPLAY) { + testPrintE("eglGetDisplay returned EGL_NO_DISPLAY"); + exit(70); + } + + returnValue = eglInitialize(*dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + if (verbose) { + testPrintI("EGL version %d.%d", majorVersion, minorVersion); + } + if (returnValue != EGL_TRUE) { + testPrintE("eglInitialize failed"); + exit(71); + } + + EGLNativeWindowType window = android_createDisplaySurface(); + if (window == NULL) { + testPrintE("android_createDisplaySurface failed"); + exit(72); + } + returnValue = EGLUtils::selectConfigForNativeWindow(*dpy, + sConfigAttribs, window, &myConfig); + if (returnValue) { + testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d", + returnValue); + exit(73); + } + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + if (verbose) { + testPrintI("Chose this configuration:"); + printEGLConfiguration(*dpy, myConfig); + } + + *surface = eglCreateWindowSurface(*dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (*surface == EGL_NO_SURFACE) { + testPrintE("gelCreateWindowSurface failed."); + exit(74); + } + + context = eglCreateContext(*dpy, myConfig, EGL_NO_CONTEXT, contextAttribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + testPrintE("eglCreateContext failed"); + exit(75); + } + returnValue = eglMakeCurrent(*dpy, *surface, *surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + testPrintE("eglMakeCurrent failed"); + exit(76); + } + eglQuerySurface(*dpy, *surface, EGL_WIDTH, width); + checkEglError("eglQuerySurface"); + eglQuerySurface(*dpy, *surface, EGL_HEIGHT, height); + checkEglError("eglQuerySurface"); + + if (verbose) { + testPrintI("Window dimensions: %d x %d", *width, *height); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + } +} + +// Open Hardware Composer Device +void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr) +{ + int rv; + hw_module_t const *hwcModule; + + if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) { + testPrintE("hw_get_module failed, rv: %i", rv); + errno = -rv; + perror(NULL); + exit(77); + } + if ((rv = hwc_open(hwcModule, hwcDevicePtr)) != 0) { + testPrintE("hwc_open failed, rv: %i", rv); + errno = -rv; + perror(NULL); + exit(78); + } +} + +// Color fraction class to string conversion +ColorFract::operator string() +{ + ostringstream out; + + out << '[' << this->c1() << ", " + << this->c2() << ", " + << this->c3() << ']'; + + return out.str(); +} + +// Dimension class to string conversion +HwcTestDim::operator string() +{ + ostringstream out; + + out << '[' << this->width() << ", " + << this->height() << ']'; + + return out.str(); +} + +// Dimension class to hwc_rect conversion +HwcTestDim::operator hwc_rect() const +{ + hwc_rect rect; + + rect.left = rect.top = 0; + + rect.right = this->_w; + rect.bottom = this->_h; + + return rect; +} + +// Hardware Composer rectangle to string conversion +string hwcTestRect2str(const struct hwc_rect& rect) +{ + ostringstream out; + + out << '['; + out << rect.left << ", "; + out << rect.top << ", "; + out << rect.right << ", "; + out << rect.bottom; + out << ']'; + + return out.str(); +} + +// Parse HWC rectangle description of form [left, top, right, bottom] +struct hwc_rect hwcTestParseHwcRect(istringstream& in, bool& error) +{ + struct hwc_rect rect; + char chStart, ch; + + // Defensively specify that an error occurred. Will clear + // error flag if all of parsing succeeds. + error = true; + + // First character should be a [ or < + in >> chStart; + if (!in || ((chStart != '<') && (chStart != '['))) { return rect; } + + // Left + in >> rect.left; + if (!in) { return rect; } + in >> ch; + if (!in || (ch != ',')) { return rect; } + + // Top + in >> rect.top; + if (!in) { return rect; } + in >> ch; + if (!in || (ch != ',')) { return rect; } + + // Right + in >> rect.right; + if (!in) { return rect; } + in >> ch; + if (!in || (ch != ',')) { return rect; } + + // Bottom + in >> rect.bottom; + if (!in) { return rect; } + + // Closing > or ] + in >> ch; + if (!in) { return rect; } + if (((chStart == '<') && (ch != '>')) + || ((chStart == '[') && (ch != ']'))) { return rect; } + + // Validate right and bottom are greater than left and top + if ((rect.right <= rect.left) || (rect.bottom <= rect.top)) { return rect; } + + // Made It, clear error indicator + error = false; + + return rect; +} + +// Parse dimension of form [width, height] +HwcTestDim hwcTestParseDim(istringstream& in, bool& error) +{ + HwcTestDim dim; + char chStart, ch; + uint32_t val; + + // Defensively specify that an error occurred. Will clear + // error flag if all of parsing succeeds. + error = true; + + // First character should be a [ or < + in >> chStart; + if (!in || ((chStart != '<') && (chStart != '['))) { return dim; } + + // Width + in >> val; + if (!in) { return dim; } + dim.setWidth(val); + in >> ch; + if (!in || (ch != ',')) { return dim; } + + // Height + in >> val; + if (!in) { return dim; } + dim.setHeight(val); + + // Closing > or ] + in >> ch; + if (!in) { return dim; } + if (((chStart == '<') && (ch != '>')) + || ((chStart == '[') && (ch != ']'))) { return dim; } + + // Validate width and height greater than 0 + if ((dim.width() <= 0) || (dim.height() <= 0)) { return dim; } + + // Made It, clear error indicator + error = false; + return dim; +} + +// Parse fractional color of form [0.##, 0.##, 0.##] +// Fractional values can be from 0.0 to 1.0 inclusive. Note, integer +// values of 0.0 and 1.0, which are non-fractional, are considered valid. +// They are an exception, all other valid inputs are fractions. +ColorFract hwcTestParseColor(istringstream& in, bool& error) +{ + ColorFract color; + char chStart, ch; + float c1, c2, c3; + + // Defensively specify that an error occurred. Will clear + // error flag if all of parsing succeeds. + error = true; + + // First character should be a [ or < + in >> chStart; + if (!in || ((chStart != '<') && (chStart != '['))) { return color; } + + // 1st Component + in >> c1; + if (!in) { return color; } + if ((c1 < 0.0) || (c1 > 1.0)) { return color; } + in >> ch; + if (!in || (ch != ',')) { return color; } + + // 2nd Component + in >> c2; + if (!in) { return color; } + if ((c2 < 0.0) || (c2 > 1.0)) { return color; } + in >> ch; + if (!in || (ch != ',')) { return color; } + + // 3rd Component + in >> c3; + if (!in) { return color; } + if ((c3 < 0.0) || (c3 > 1.0)) { return color; } + + // Closing > or ] + in >> ch; + if (!in) { return color; } + if (((chStart == '<') && (ch != '>')) + || ((chStart == '[') && (ch != ']'))) { return color; } + + // Are all the components fractional + if ((c1 < 0.0) || (c1 > 1.0) + || (c2 < 0.0) || (c2 > 1.0) + || (c3 < 0.0) || (c3 > 1.0)) { return color; } + + // Made It, clear error indicator + error = false; + + return ColorFract(c1, c2, c3); +} + +// Look up and return pointer to structure with the characteristics +// of the graphic format named by the desc parameter. Search failure +// indicated by the return of NULL. +const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc) +{ + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + if (string(desc) == string(hwcTestGraphicFormat[n1].desc)) { + return &hwcTestGraphicFormat[n1]; + } + } + + return NULL; +} + +// Look up and return pointer to structure with the characteristics +// of the graphic format specified by the id parameter. Search failure +// indicated by the return of NULL. +const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id) +{ + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + if (id == hwcTestGraphicFormat[n1].format) { + return &hwcTestGraphicFormat[n1]; + } + } + + return NULL; +} + + +// Given the integer ID of a graphic format, return a pointer to +// a string that describes the format. +const char *hwcTestGraphicFormat2str(uint32_t format) +{ + const static char *unknown = "unknown"; + + for (unsigned int n1 = 0; n1 < NUMA(hwcTestGraphicFormat); n1++) { + if (format == hwcTestGraphicFormat[n1].format) { + return hwcTestGraphicFormat[n1].desc; + } + } + + return unknown; +} + +/* + * hwcTestCreateLayerList + * Dynamically creates layer list with numLayers worth + * of hwLayers entries. + */ +hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers) +{ + hwc_layer_list_t *list; + + size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t); + if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) { + return NULL; + } + list->flags = HWC_GEOMETRY_CHANGED; + list->numHwLayers = numLayers; + + return list; +} + +/* + * hwcTestFreeLayerList + * Frees memory previous allocated via hwcTestCreateLayerList(). + */ +void hwcTestFreeLayerList(hwc_layer_list_t *list) +{ + free(list); +} + +// Display the settings of the layer list pointed to by list +void hwcTestDisplayList(hwc_layer_list_t *list) +{ + testPrintI(" flags: %#x%s", list->flags, + (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : ""); + testPrintI(" numHwLayers: %u", list->numHwLayers); + + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + testPrintI(" layer %u compositionType: %#x%s%s", layer, + list->hwLayers[layer].compositionType, + (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER) + ? " FRAMEBUFFER" : "", + (list->hwLayers[layer].compositionType == HWC_OVERLAY) + ? " OVERLAY" : ""); + + testPrintI(" hints: %#x", + list->hwLayers[layer].hints, + (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER) + ? " TRIPLE_BUFFER" : "", + (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB) + ? " CLEAR_FB" : ""); + + testPrintI(" flags: %#x%s", + list->hwLayers[layer].flags, + (list->hwLayers[layer].flags & HWC_SKIP_LAYER) + ? " SKIP_LAYER" : ""); + + testPrintI(" handle: %p", + list->hwLayers[layer].handle); + + // Intentionally skipped display of ROT_180 & ROT_270, + // which are formed from combinations of the other flags. + testPrintI(" transform: %#x%s%s%s", + list->hwLayers[layer].transform, + (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H) + ? " FLIP_H" : "", + (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V) + ? " FLIP_V" : "", + (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90) + ? " ROT_90" : ""); + + testPrintI(" blending: %#x%s%s%s", + list->hwLayers[layer].blending, + (list->hwLayers[layer].blending == HWC_BLENDING_NONE) + ? " NONE" : "", + (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT) + ? " PREMULT" : "", + (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE) + ? " COVERAGE" : ""); + + testPrintI(" sourceCrop: %s", + hwcTestRect2str(list->hwLayers[layer].sourceCrop).c_str()); + testPrintI(" displayFrame: %s", + hwcTestRect2str(list->hwLayers[layer].displayFrame).c_str()); + testPrintI(" scaleFactor: [%f, %f]", + (float) (list->hwLayers[layer].sourceCrop.right + - list->hwLayers[layer].sourceCrop.left) + / (float) (list->hwLayers[layer].displayFrame.right + - list->hwLayers[layer].displayFrame.left), + (float) (list->hwLayers[layer].sourceCrop.bottom + - list->hwLayers[layer].sourceCrop.top) + / (float) (list->hwLayers[layer].displayFrame.bottom + - list->hwLayers[layer].displayFrame.top)); + } +} + +/* + * Display List Prepare Modifiable + * + * Displays the portions of a list that are meant to be modified by + * a prepare call. + */ +void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list) +{ + uint32_t numOverlays = 0; + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + if (list->hwLayers[layer].compositionType == HWC_OVERLAY) { + numOverlays++; + } + testPrintI(" layer %u compositionType: %#x%s%s", layer, + list->hwLayers[layer].compositionType, + (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER) + ? " FRAMEBUFFER" : "", + (list->hwLayers[layer].compositionType == HWC_OVERLAY) + ? " OVERLAY" : ""); + testPrintI(" hints: %#x%s%s", + list->hwLayers[layer].hints, + (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER) + ? " TRIPLE_BUFFER" : "", + (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB) + ? " CLEAR_FB" : ""); + } + testPrintI(" numOverlays: %u", numOverlays); +} + +/* + * Display List Handles + * + * Displays the handles of all the graphic buffers in the list. + */ +void hwcTestDisplayListHandles(hwc_layer_list_t *list) +{ + const unsigned int maxLayersPerLine = 6; + + ostringstream str(" layers:"); + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + str << ' ' << list->hwLayers[layer].handle; + if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1)) + && (layer != list->numHwLayers - 1)) { + testPrintI("%s", str.str().c_str()); + str.str(" "); + } + } + testPrintI("%s", str.str().c_str()); +} + +// Returns a uint32_t that contains a format specific representation of a +// single pixel of the given color and alpha values. +uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha) +{ + const struct attrib { + uint32_t format; + bool hostByteOrder; + size_t bytes; + size_t c1Offset; + size_t c1Size; + size_t c2Offset; + size_t c2Size; + size_t c3Offset; + size_t c3Size; + size_t aOffset; + size_t aSize; + } attributes[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, false, 4, 0, 8, 8, 8, 16, 8, 24, 8}, + {HAL_PIXEL_FORMAT_RGBX_8888, false, 4, 0, 8, 8, 8, 16, 8, 0, 0}, + {HAL_PIXEL_FORMAT_RGB_888, false, 3, 0, 8, 8, 8, 16, 8, 0, 0}, + {HAL_PIXEL_FORMAT_RGB_565, true, 2, 0, 5, 5, 6, 11, 5, 0, 0}, + {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8, 8, 8, 0, 8, 24, 8}, + {HAL_PIXEL_FORMAT_RGBA_5551, true , 2, 0, 5, 5, 5, 10, 5, 15, 1}, + {HAL_PIXEL_FORMAT_RGBA_4444, false, 2, 12, 4, 0, 4, 4, 4, 8, 4}, + {HAL_PIXEL_FORMAT_YV12, true, 3, 16, 8, 8, 8, 0, 8, 0, 0}, + }; + + const struct attrib *attrib; + for (attrib = attributes; attrib < attributes + NUMA(attributes); + attrib++) { + if (attrib->format == format) { break; } + } + if (attrib >= attributes + NUMA(attributes)) { + testPrintE("colorFract2Pixel unsupported format of: %u", format); + exit(80); + } + + uint32_t pixel; + pixel = htonl((uint32_t) round((((1 << attrib->c1Size) - 1) * color.c1())) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->c1Offset + attrib->c1Size))); + pixel |= htonl((uint32_t) round((((1 << attrib->c2Size) - 1) * color.c2())) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->c2Offset + attrib->c2Size))); + pixel |= htonl((uint32_t) round((((1 << attrib->c3Size) - 1) * color.c3())) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->c3Offset + attrib->c3Size))); + if (attrib->aSize) { + pixel |= htonl((uint32_t) round((((1 << attrib->aSize) - 1) * alpha)) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->aOffset + attrib->aSize))); + } + if (attrib->hostByteOrder) { + pixel = ntohl(pixel); + pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE; + } + + return pixel; +} + +// Sets the pixel at the given x and y coordinates to the color and alpha +// value given by pixel. The contents of pixel is format specific. It's +// value should come from a call to hwcTestColor2Pixel(). +void hwcTestSetPixel(GraphicBuffer *gBuf, unsigned char *buf, + uint32_t x, uint32_t y, uint32_t pixel) +{ + + const struct attrib { + int format; + size_t bytes; + } attributes[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, 4}, + {HAL_PIXEL_FORMAT_RGBX_8888, 4}, + {HAL_PIXEL_FORMAT_RGB_888, 3}, + {HAL_PIXEL_FORMAT_RGB_565, 2}, + {HAL_PIXEL_FORMAT_BGRA_8888, 4}, + {HAL_PIXEL_FORMAT_RGBA_5551, 2}, + {HAL_PIXEL_FORMAT_RGBA_4444, 2}, + }; + + if (gBuf->getPixelFormat() == HAL_PIXEL_FORMAT_YV12) { + uint32_t yPlaneOffset, uPlaneOffset, vPlaneOffset; + uint32_t yPlaneStride = gBuf->getStride(); + uint32_t uPlaneStride = ((gBuf->getStride() / 2) + 0xf) & ~0xf; + uint32_t vPlaneStride = uPlaneStride; + yPlaneOffset = 0; + vPlaneOffset = yPlaneOffset + yPlaneStride * gBuf->getHeight(); + uPlaneOffset = vPlaneOffset + + vPlaneStride * (gBuf->getHeight() / 2); + *(buf + yPlaneOffset + y * yPlaneStride + x) = pixel & 0xff; + *(buf + uPlaneOffset + (y / 2) * uPlaneStride + (x / 2)) + = (pixel & 0xff00) >> 8; + *(buf + vPlaneOffset + (y / 2) * vPlaneStride + (x / 2)) + = (pixel & 0xff0000) >> 16; + + return; + } + + const struct attrib *attrib; + for (attrib = attributes; attrib < attributes + NUMA(attributes); + attrib++) { + if (attrib->format == gBuf->getPixelFormat()) { break; } + } + if (attrib >= attributes + NUMA(attributes)) { + testPrintE("setPixel unsupported format of: %u", + gBuf->getPixelFormat()); + exit(90); + } + + memmove(buf + ((gBuf->getStride() * attrib->bytes) * y) + + (attrib->bytes * x), &pixel, attrib->bytes); +} + +// Fill a given graphic buffer with a uniform color and alpha +void hwcTestFillColor(GraphicBuffer *gBuf, ColorFract color, float alpha) +{ + unsigned char* buf = NULL; + status_t err; + uint32_t pixel; + + pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, alpha); + + err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + testPrintE("hwcTestFillColor lock failed: %d", err); + exit(100); + } + + for (unsigned int x = 0; x < gBuf->getStride(); x++) { + for (unsigned int y = 0; y < gBuf->getHeight(); y++) { + uint32_t val = pixel; + hwcTestSetPixel(gBuf, buf, x, y, (x < gBuf->getWidth()) + ? pixel : testRand()); + } + } + + err = gBuf->unlock(); + if (err != 0) { + testPrintE("hwcTestFillColor unlock failed: %d", err); + exit(101); + } +} + +// Fill the given buffer with a horizontal blend of colors, with the left +// side color given by startColor and the right side color given by +// endColor. The startColor and endColor values are specified in the format +// given by colorFormat, which might be different from the format of the +// graphic buffer. When different, a color conversion is done when possible +// to the graphic format of the graphic buffer. A color of black is +// produced for cases where the conversion is impossible (e.g. out of gamut +// values). +void hwcTestFillColorHBlend(GraphicBuffer *gBuf, uint32_t colorFormat, + ColorFract startColor, ColorFract endColor) +{ + status_t err; + unsigned char* buf = NULL; + const uint32_t width = gBuf->getWidth(); + const uint32_t height = gBuf->getHeight(); + const uint32_t stride = gBuf->getStride(); + + err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + testPrintE("hwcTestFillColorHBlend lock failed: %d", err); + exit(110); + } + + for (unsigned int x = 0; x < stride; x++) { + uint32_t pixel; + if (x < width) { + ColorFract color(startColor.c1() + (endColor.c1() - startColor.c1()) + * ((float) x / (float) (width - 1)), + startColor.c2() + (endColor.c2() - startColor.c2()) + * ((float) x / (float) (width - 1)), + startColor.c3() + (endColor.c3() - startColor.c3()) + * ((float) x / (float) (width - 1))); + + // When formats differ, convert colors. + // Important to not convert when formats are the same, since + // out of gamut colors are always converted to black. + if (colorFormat != (uint32_t) gBuf->getPixelFormat()) { + hwcTestColorConvert(colorFormat, gBuf->getPixelFormat(), color); + } + pixel = hwcTestColor2Pixel(gBuf->getPixelFormat(), color, 1.0); + } else { + // Fill pad with random values + pixel = testRand(); + } + + for (unsigned int y = 0; y < height; y++) { + hwcTestSetPixel(gBuf, buf, x, y, pixel); + } + } + + err = gBuf->unlock(); + if (err != 0) { + testPrintE("hwcTestFillColorHBlend unlock failed: %d", err); + exit(111); + } +} + +/* + * When possible, converts color specified as a full range value in + * the fromFormat, into an equivalent full range color in the toFormat. + * When conversion is impossible (e.g. out of gamut color) a color + * or black in the full range output format is produced. The input + * color is given as a fractional color in the parameter named color. + * The produced color is written over the same parameter used to + * provide the input color. + * + * Each graphic format has 3 color components and each of these + * components has both a full and in gamut range. This function uses + * a table that provides the full and in gamut ranges of each of the + * supported graphic formats. The full range is given by members named + * c[123]Min to c[123]Max, while the in gamut range is given by members + * named c[123]Low to c[123]High. In most cases the full and in gamut + * ranges are equivalent. This occurs when the c[123]Min == c[123]Low and + * c[123]High == c[123]Max. + * + * The input and produced colors are both specified as a fractional amount + * of the full range. The diagram below provides an overview of the + * conversion process. The main steps are: + * + * 1. Produce black if the input color is out of gamut. + * + * 2. Convert the in gamut color into the fraction of the fromFromat + * in gamut range. + * + * 3. Convert from the fraction of the in gamut from format range to + * the fraction of the in gamut to format range. Produce black + * if an equivalent color does not exists. + * + * 4. Covert from the fraction of the in gamut to format to the + * fraction of the full range to format. + * + * From Format To Format + * max high high max + * ----+ +-----------+ + * high \ / \ high + * ------\-------------+ +--------> + * \ + * \ +--- black --+ + * \ / \ + * \ / +--> + * low \ / low + * -------- ---+-- black --+ + * min low low min + * ^ ^ ^ ^ ^ + * | | | | | + * | | | | +-- fraction of full range + * | | | +-- fraction of valid range + * | | +-- fromFormat to toFormat color conversion + * | +-- fraction of valid range + * +-- fraction of full range + */ +void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat, + ColorFract& color) +{ + const struct attrib { + uint32_t format; + bool rgb; + bool yuv; + int c1Min, c1Low, c1High, c1Max; + int c2Min, c2Low, c2High, c2Max; + int c3Min, c3Low, c3High, c3Max; + } attributes[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, true, false, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255}, + {HAL_PIXEL_FORMAT_RGBX_8888, true, false, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255}, + {HAL_PIXEL_FORMAT_RGB_888, true, false, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255}, + {HAL_PIXEL_FORMAT_RGB_565, true, false, + 0, 0, 31, 31, 0, 0, 63, 63, 0, 0, 31, 31}, + {HAL_PIXEL_FORMAT_BGRA_8888, true, false, + 0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 255, 255}, + {HAL_PIXEL_FORMAT_RGBA_5551, true, false, + 0, 0, 31, 31, 0, 0, 31, 31, 0, 0, 31, 31}, + {HAL_PIXEL_FORMAT_RGBA_4444, true, false, + 0, 0, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15}, + {HAL_PIXEL_FORMAT_YV12, false, true, + 0, 16, 235, 255, 0, 16, 240, 255, 0, 16, 240, 255}, + }; + + const struct attrib *fromAttrib; + for (fromAttrib = attributes; fromAttrib < attributes + NUMA(attributes); + fromAttrib++) { + if (fromAttrib->format == fromFormat) { break; } + } + if (fromAttrib >= attributes + NUMA(attributes)) { + testPrintE("hwcTestColorConvert unsupported from format of: %u", + fromFormat); + exit(120); + } + + const struct attrib *toAttrib; + for (toAttrib = attributes; toAttrib < attributes + NUMA(attributes); + toAttrib++) { + if (toAttrib->format == toFormat) { break; } + } + if (toAttrib >= attributes + NUMA(attributes)) { + testPrintE("hwcTestColorConvert unsupported to format of: %u", + toFormat); + exit(121); + } + + // Produce black if any of the from components are outside the + // valid color range + float c1Val = fromAttrib->c1Min + + ((float) (fromAttrib->c1Max - fromAttrib->c1Min) * color.c1()); + float c2Val = fromAttrib->c2Min + + ((float) (fromAttrib->c2Max - fromAttrib->c2Min) * color.c2()); + float c3Val = fromAttrib->c3Min + + ((float) (fromAttrib->c3Max - fromAttrib->c3Min) * color.c3()); + if ((c1Val < fromAttrib->c1Low) || (c1Val > fromAttrib->c1High) + || (c2Val < fromAttrib->c2Low) || (c2Val > fromAttrib->c2High) + || (c3Val < fromAttrib->c3Low) || (c3Val > fromAttrib->c3High)) { + + // Return black + // Will use representation of black from RGBA8888 graphic format + // and recursively convert it to the requested graphic format. + color = ColorFract(0.0, 0.0, 0.0); + hwcTestColorConvert(HAL_PIXEL_FORMAT_RGBA_8888, toFormat, color); + return; + } + + // Within from format, convert from fraction of full range + // to fraction of valid range + color = ColorFract((c1Val - fromAttrib->c1Low) + / (fromAttrib->c1High - fromAttrib->c1Low), + (c2Val - fromAttrib->c2Low) + / (fromAttrib->c2High - fromAttrib->c2Low), + (c3Val - fromAttrib->c3Low) + / (fromAttrib->c3High - fromAttrib->c3Low)); + + // If needed perform RGB to YUV conversion + float wr = 0.2126, wg = 0.7152, wb = 0.0722; // ITU709 recommended constants + if (fromAttrib->rgb && toAttrib->yuv) { + float r = color.c1(), g = color.c2(), b = color.c3(); + float y = wr * r + wg * g + wb * b; + float u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5; + float v = 0.5 * ((r - y) / (1.0 - wr)) + 0.5; + + // Produce black if color is outside the YUV gamut + if ((y < 0.0) || (y > 1.0) + || (u < 0.0) || (u > 1.0) + || (v < 0.0) || (v > 1.0)) { + y = 0.0; + u = v = 0.5; + } + + color = ColorFract(y, u, v); + } + + // If needed perform YUV to RGB conversion + // Equations determined from the ITU709 equations for RGB to YUV + // conversion, plus the following algebra: + // + // u = 0.5 * ((b - y) / (1.0 - wb)) + 0.5 + // 0.5 * ((b - y) / (1.0 - wb)) = u - 0.5 + // (b - y) / (1.0 - wb) = 2 * (u - 0.5) + // b - y = 2 * (u - 0.5) * (1.0 - wb) + // b = 2 * (u - 0.5) * (1.0 - wb) + y + // + // v = 0.5 * ((r -y) / (1.0 - wr)) + 0.5 + // 0.5 * ((r - y) / (1.0 - wr)) = v - 0.5 + // (r - y) / (1.0 - wr) = 2 * (v - 0.5) + // r - y = 2 * (v - 0.5) * (1.0 - wr) + // r = 2 * (v - 0.5) * (1.0 - wr) + y + // + // y = wr * r + wg * g + wb * b + // wr * r + wg * g + wb * b = y + // wg * g = y - wr * r - wb * b + // g = (y - wr * r - wb * b) / wg + if (fromAttrib->yuv && toAttrib->rgb) { + float y = color.c1(), u = color.c2(), v = color.c3(); + float r = 2.0 * (v - 0.5) * (1.0 - wr) + y; + float b = 2.0 * (u - 0.5) * (1.0 - wb) + y; + float g = (y - wr * r - wb * b) / wg; + + // Produce black if color is outside the RGB gamut + if ((r < 0.0) || (r > 1.0) + || (g < 0.0) || (g > 1.0) + || (b < 0.0) || (b > 1.0)) { + r = g = b = 0.0; + } + + color = ColorFract(r, g, b); + } + + // Within to format, convert from fraction of valid range + // to fraction of full range + c1Val = (toAttrib->c1Low + + (float) (toAttrib->c1High - toAttrib->c1Low) * color.c1()); + c2Val = (toAttrib->c1Low + + (float) (toAttrib->c2High - toAttrib->c2Low) * color.c2()); + c3Val = (toAttrib->c1Low + + (float) (toAttrib->c3High - toAttrib->c3Low) * color.c3()); + color = ColorFract((float) (c1Val - toAttrib->c1Min) + / (float) (toAttrib->c1Max - toAttrib->c1Min), + (float) (c2Val - toAttrib->c2Min) + / (float) (toAttrib->c2Max - toAttrib->c2Min), + (float) (c3Val - toAttrib->c3Min) + / (float) (toAttrib->c3Max - toAttrib->c3Min)); +} + +// TODO: Use PrintGLString, CechckGlError, and PrintEGLConfiguration +// from libglTest +static void printGLString(const char *name, GLenum s) +{ + const char *v = (const char *) glGetString(s); + + if (v == NULL) { + testPrintI("GL %s unknown", name); + } else { + testPrintI("GL %s = %s", name, v); + } +} + +static void checkEglError(const char* op, EGLBoolean returnVal) +{ + if (returnVal != EGL_TRUE) { + testPrintE("%s() returned %d", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + testPrintE("after %s() eglError %s (0x%x)", + op, EGLUtils::strerror(error), error); + } +} + +static void checkGlError(const char* op) +{ + for (GLint error = glGetError(); error; error + = glGetError()) { + testPrintE("after %s() glError (0x%x)", op, error); + } +} + +static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) +{ + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, + &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + testPrintI(" %s: %d (%#x)", names[j].name, value, value); + } + } + testPrintI(""); +} diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h new file mode 100644 index 0000000..99ee608 --- /dev/null +++ b/opengl/tests/hwc/hwcTestLib.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Hardware Composer Test Library Header + */ + +#include <sstream> +#include <string> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +// Characteristics of known graphic formats +const struct hwcTestGraphicFormat { + uint32_t format; + const char *desc; + uint32_t wMod, hMod; // Width/height mod this value must equal zero +} hwcTestGraphicFormat[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888", 1, 1}, + {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888", 1, 1}, + {HAL_PIXEL_FORMAT_RGB_888, "RGB888", 1, 1}, + {HAL_PIXEL_FORMAT_RGB_565, "RGB565", 1, 1}, + {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888", 1, 1}, + {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551", 1, 1}, + {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444", 1, 1}, + {HAL_PIXEL_FORMAT_YV12, "YV12", 2, 2}, +}; + +// Represent RGB color as fraction of color components. +// Each of the color components are expected in the range [0.0, 1.0] +class ColorFract { + public: + ColorFract(): _c1(0.0), _c2(0.0), _c3(0.0) {}; + ColorFract(float c1, float c2, float c3): _c1(c1), _c2(c2), _c3(c3) {}; + float c1(void) const { return _c1; } + float c2(void) const { return _c2; } + float c3(void) const { return _c3; } + + operator std::string(); + + private: + float _c1; + float _c2; + float _c3; +}; + +// Represent RGB color as fraction of color components. +// Each of the color components are expected in the range [0.0, 1.0] +class ColorRGB { + public: + ColorRGB(): _r(0.0), _g(0.0), _b(0.0) {}; + ColorRGB(float f): _r(f), _g(f), _b(f) {}; // Gray + ColorRGB(float r, float g, float b): _r(r), _g(g), _b(b) {}; + float r(void) const { return _r; } + float g(void) const { return _g; } + float b(void) const { return _b; } + + private: + float _r; + float _g; + float _b; +}; + +// Dimension - width and height of a rectanguler area +class HwcTestDim { + public: + HwcTestDim(): _w(0), _h(0) {}; + HwcTestDim(uint32_t w, uint32_t h) : _w(w), _h(h) {} + uint32_t width(void) const { return _w; } + uint32_t height(void) const { return _h; } + void setWidth(uint32_t w) { _w = w; } + void setHeight(uint32_t h) { _h = h; } + + operator std::string(); + operator hwc_rect() const; + + private: + uint32_t _w; + uint32_t _h; +}; + +// Function Prototypes +void hwcTestInitDisplay(bool verbose, EGLDisplay *dpy, EGLSurface *surface, + EGLint *width, EGLint *height); +void hwcTestOpenHwc(hwc_composer_device_t **hwcDevicePtr); +const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(const char *desc); +const struct hwcTestGraphicFormat *hwcTestGraphicFormatLookup(uint32_t id); +const char *hwcTestGraphicFormat2str(uint32_t format); +std::string hwcTestRect2str(const struct hwc_rect& rect); + +hwc_layer_list_t *hwcTestCreateLayerList(size_t numLayers); +void hwcTestFreeLayerList(hwc_layer_list_t *list); +void hwcTestDisplayList(hwc_layer_list_t *list); +void hwcTestDisplayListPrepareModifiable(hwc_layer_list_t *list); +void hwcTestDisplayListHandles(hwc_layer_list_t *list); + +uint32_t hwcTestColor2Pixel(uint32_t format, ColorFract color, float alpha); +void hwcTestColorConvert(uint32_t fromFormat, uint32_t toFormat, + ColorFract& color); +void hwcTestSetPixel(android::GraphicBuffer *gBuf, unsigned char *buf, + uint32_t x, uint32_t y, uint32_t pixel); +void hwcTestFillColor(android::GraphicBuffer *gBuf, ColorFract color, + float alpha); +void hwcTestFillColorHBlend(android::GraphicBuffer *gBuf, + uint32_t colorFormat, + ColorFract startColor, ColorFract endColor); +ColorFract hwcTestParseColor(std::istringstream& in, bool& error); +struct hwc_rect hwcTestParseHwcRect(std::istringstream& in, bool& error); +HwcTestDim hwcTestParseDim(std::istringstream& in, bool& error); diff --git a/opengl/tests/include/glTestLib.h b/opengl/tests/include/glTestLib.h new file mode 100644 index 0000000..06fbf5d --- /dev/null +++ b/opengl/tests/include/glTestLib.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Graphics Test Library Header + */ + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +//#include <ui/FramebufferNativeWindow.h> +//#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +void glTestPrintGLString(const char *name, GLenum s); +void glTestCheckEglError(const char* op, EGLBoolean returnVal = EGL_TRUE); +void glTestCheckGlError(const char* op); +void glTestPrintEGLConfiguration(EGLDisplay dpy, EGLConfig config); diff --git a/opengl/tests/lib/Android.mk b/opengl/tests/lib/Android.mk new file mode 100644 index 0000000..7542ac4 --- /dev/null +++ b/opengl/tests/lib/Android.mk @@ -0,0 +1,32 @@ +# Copyright (C) 2010 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. + +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := tests +LOCAL_MODULE:= libglTest +LOCAL_SRC_FILES:= glTestLib.cpp +LOCAL_C_INCLUDES += system/extras/tests/include \ + bionic \ + bionic/libstdc++/include \ + external/stlport/stlport \ + frameworks/base/opengl/tests/include \ + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +LOCAL_SHARED_LIBRARIES += libcutils libutils libstlport +LOCAL_PRELINK_MODULE := false + +include $(BUILD_STATIC_LIBRARY) diff --git a/opengl/tests/lib/glTestLib.cpp b/opengl/tests/lib/glTestLib.cpp new file mode 100644 index 0000000..052cbd7 --- /dev/null +++ b/opengl/tests/lib/glTestLib.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2011 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. + * + */ + +/* + * Graphics Test Library + */ + +#include <glTestLib.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/EGLUtils.h> + +#include <utils/Log.h> +#include <testUtil.h> + +using namespace std; +using namespace android; + +void glTestPrintGLString(const char *name, GLenum s) +{ + const char *v = (const char *) glGetString(s); + + if (v == NULL) { + testPrintI("GL %s unknown", name); + } else { + testPrintI("GL %s = %s", name, v); + } +} + +void glTestCheckEglError(const char* op, EGLBoolean returnVal) +{ + if (returnVal != EGL_TRUE) { + testPrintE("%s() returned %d", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + testPrintE("after %s() eglError %s (0x%x)", + op, EGLUtils::strerror(error), error); + } +} + +void glTestCheckGlError(const char* op) +{ + for (GLint error = glGetError(); error; error + = glGetError()) { + testPrintE("after %s() glError (0x%x)", op, error); + } +} + +void glTestPrintEGLConfiguration(EGLDisplay dpy, EGLConfig config) +{ + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, + &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + testPrintI(" %s: %d (%#x)", names[j].name, value, value); + } + } + testPrintI(""); +} diff --git a/opengl/tests/testFramerate/Android.mk b/opengl/tests/testFramerate/Android.mk new file mode 100644 index 0000000..500abf3 --- /dev/null +++ b/opengl/tests/testFramerate/Android.mk @@ -0,0 +1,19 @@ +######################################################################### +# Test framerate and look for hiccups +######################################################################### + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestFramerate + +include $(BUILD_PACKAGE) diff --git a/opengl/tests/testFramerate/AndroidManifest.xml b/opengl/tests/testFramerate/AndroidManifest.xml new file mode 100644 index 0000000..85617f4 --- /dev/null +++ b/opengl/tests/testFramerate/AndroidManifest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testframerate"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + + <application + android:label="@string/testFramerate_activity"> + <activity android:name="TestFramerateActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testFramerate/res/values/strings.xml b/opengl/tests/testFramerate/res/values/strings.xml new file mode 100644 index 0000000..baadf0e --- /dev/null +++ b/opengl/tests/testFramerate/res/values/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2006 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. +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="testFramerate_activity">TestFramerate</string> + +</resources> + diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java new file mode 100644 index 0000000..cbe279b --- /dev/null +++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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.testframerate; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class TestFramerateActivity extends Activity { + + TestFramerateView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestFramerateView(getApplication()); + setContentView(mView); + mView.setFocusableInTouchMode(true); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java new file mode 100644 index 0000000..f3fb5de --- /dev/null +++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 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.testframerate; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.os.SystemProperties; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLES20; + +class TestFramerateView extends GLSurfaceView { + private static String TAG = "TestFramerateView"; + + public TestFramerateView(Context context) { + super(context); + setEGLContextClientVersion(2); + setRenderer(new Renderer()); + } + + private long mLastTime_us = 0; + private long mNumShortFramesElapsed = 0; + private void registerTime(long now_us) { + long longFrameTime_ms = Integer.parseInt(SystemProperties.get("debug.longframe_ms", "16")); + long elapsedTime_us = now_us - mLastTime_us; + float fps = 1000000.f / elapsedTime_us; + if (mLastTime_us > 0 && elapsedTime_us > longFrameTime_ms*1000) { + Log.v(TAG, "Long frame: " + elapsedTime_us/1000.f + " ms (" + fps + " fps)"); + if (mNumShortFramesElapsed > 0) { + Log.v(TAG, " Short frames since last long frame: " + mNumShortFramesElapsed); + mNumShortFramesElapsed = 0; + } + } else { + ++mNumShortFramesElapsed; + } + + mLastTime_us = now_us; + } + + private class Renderer implements GLSurfaceView.Renderer { + public Renderer() { + } + + + public void onDrawFrame(GL10 gl) { + long now_us = System.nanoTime() / 1000; + registerTime(now_us); + + float red = (now_us % 1000000) / 1000000.f; + float green = (now_us % 2000000) / 2000000.f; + float blue = (now_us % 3000000) / 3000000.f; + GLES20.glClearColor(red, green, blue, 1.0f); + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLES20.glViewport(0, 0, width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + } + + } +} diff --git a/opengl/tests/testLatency/Android.mk b/opengl/tests/testLatency/Android.mk new file mode 100644 index 0000000..96417c7 --- /dev/null +++ b/opengl/tests/testLatency/Android.mk @@ -0,0 +1,20 @@ +######################################################################### +# Test end-to-end latency. +######################################################################### + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SDK_VERSION := 8 +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestLatency + +include $(BUILD_PACKAGE) diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml new file mode 100644 index 0000000..59f2643 --- /dev/null +++ b/opengl/tests/testLatency/AndroidManifest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testlatency"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + + <application + android:label="@string/testLatency_activity"> + <activity android:name="TestLatencyActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml new file mode 100644 index 0000000..d80b77c --- /dev/null +++ b/opengl/tests/testLatency/res/values/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2006 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. +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="testLatency_activity">TestLatency</string> + +</resources> + diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java new file mode 100644 index 0000000..ed993cb --- /dev/null +++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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.testlatency; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class TestLatencyActivity extends Activity { + + TestLatencyView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestLatencyView(getApplication()); + setContentView(mView); + mView.setFocusableInTouchMode(true); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java new file mode 100644 index 0000000..d62bf17 --- /dev/null +++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2009 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.testlatency; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLES20; + +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class TestLatencyView extends GLSurfaceView { + private static String TAG = "TestLatencyiew"; + private float mX; + private float mY; + private float mDX; + private float mDY; + private long mT; + private long mDT; + + public TestLatencyView(Context context) { + super(context); + setEGLContextClientVersion(2); + setRenderer(new Renderer()); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_MOVE: + float x = event.getX(); + float y = event.getY(); + long t = event.getEventTime(); + synchronized(this) { + mDT = t - mT; + mT = t; + mDX = x - mX; + mX = x; + mDY = y - mY; + mY = y; + } + break; + default: + break; + } + return true; + } + + private class Renderer implements GLSurfaceView.Renderer { + private float mScaleX, mScaleY, mOffsetX, mOffsetY; + private final float MS_PER_FRAME = 1000 / 60; + public Renderer() { + mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + } + + + public void onDrawFrame(GL10 gl) { + GLES20.glClearColor(0.4f, 0.4f, 0.4f, 1.0f); + GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); + GLES20.glUseProgram(mProgram); + checkGlError("glUseProgram"); + + float x, y, dx, dy; + long t, dt; + synchronized(TestLatencyView.this) { + x = mX; + y = mY; + dx = mDX; + dy = mDY; + dt = mDT; + } + + if (dt > 0) { + dx = dx * MS_PER_FRAME / dt; + dy = dy * MS_PER_FRAME / dt; + } + + GLES20.glEnableVertexAttribArray(mvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + GLES20.glEnableVertexAttribArray(mvColorHandle); + checkGlError("glEnableVertexAttribArray"); + for(int step = 0; step < 8; step++) { + float sx = (x + dx * step) * mScaleX + mOffsetX; + float sy = (y + dy * step) * mScaleY + mOffsetY; + int cbase = step * 4; + + for (int i = 0; i < mTriangleVerticesData.length; i += 6) { + mTriangleVerticesData2[i] = sx + mTriangleVerticesData[i]; + mTriangleVerticesData2[i+1] = -sy + mTriangleVerticesData[i+1]; + mTriangleVerticesData2[i+2] = mColors[cbase]; + mTriangleVerticesData2[i+3] = mColors[cbase+1]; + mTriangleVerticesData2[i+4] = mColors[cbase+2]; + mTriangleVerticesData2[i+5] = mColors[cbase+3]; + } + mTriangleVertices.position(0); + mTriangleVertices.put(mTriangleVerticesData2).position(0); + + GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices); + checkGlError("glVertexAttribPointer mvPosition"); + mTriangleVertices.put(mTriangleVerticesData2).position(2); + GLES20.glVertexAttribPointer(mvColorHandle, 4, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices); + checkGlError("glVertexAttribPointer mvColor"); + GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); + checkGlError("glDrawArrays"); + } + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLES20.glViewport(0, 0, width, height); + mScaleX = 2.0f / width; + mScaleY = 2.0f / height; + mOffsetX = -1f; + mOffsetY = -1f; + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + mProgram = createProgram(mVertexShader, mFragmentShader); + if (mProgram == 0) { + return; + } + mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); + checkGlError("glGetAttribLocation"); + if (mvPositionHandle == -1) { + throw new RuntimeException("Could not get attrib location for vPosition"); + } + mvColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor"); + checkGlError("glGetAttribLocation"); + if (mvColorHandle == -1) { + throw new RuntimeException("Could not get attrib location for vColor"); + } + } + + private int loadShader(int shaderType, String source) { + int shader = GLES20.glCreateShader(shaderType); + if (shader != 0) { + GLES20.glShaderSource(shader, source); + GLES20.glCompileShader(shader); + int[] compiled = new int[1]; + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); + if (compiled[0] == 0) { + Log.e(TAG, "Could not compile shader " + shaderType + ":"); + Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); + GLES20.glDeleteShader(shader); + shader = 0; + } + } + return shader; + } + + private int createProgram(String vertexSource, String fragmentSource) { + int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); + if (vertexShader == 0) { + return 0; + } + + int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); + if (pixelShader == 0) { + return 0; + } + + int program = GLES20.glCreateProgram(); + if (program != 0) { + GLES20.glAttachShader(program, vertexShader); + checkGlError("glAttachShader vertexShader"); + GLES20.glAttachShader(program, pixelShader); + checkGlError("glAttachShader pixelShader"); + GLES20.glLinkProgram(program); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] != GLES20.GL_TRUE) { + Log.e(TAG, "Could not link program: "); + Log.e(TAG, GLES20.glGetProgramInfoLog(program)); + GLES20.glDeleteProgram(program); + program = 0; + } + } + return program; + } + + private void checkGlError(String op) { + int error; + while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { + Log.e(TAG, op + ": glError " + error); + throw new RuntimeException(op + ": glError " + error); + } + } + + // X, Y, R G B A + private final float[] mTriangleVerticesData = { + -0.025f, 0.3f, 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f , 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + 0.025f, 0.3f, 1.0f, 1.0f, 255.0f, 1.0f + }; + + // Color cascade: + private final float[] mColors = { + 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.0f, 1.0f, + + 0.0f, 0.0f, 0.5f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f + }; + + private float[] mTriangleVerticesData2 = new float[mTriangleVerticesData.length]; + private FloatBuffer mTriangleVertices; + + private final String mVertexShader = "attribute vec4 aPosition;\n" + + "attribute vec4 aColor;\n" + + "varying vec4 vColor;\n" + + "void main() {\n" + + " gl_Position = aPosition;\n" + + " vColor = aColor;\n" + + "}\n"; + + private final String mFragmentShader = "precision mediump float;\n" + + "varying vec4 vColor;\n" + + "void main() {\n" + + " gl_FragColor = vColor;\n" + + "}\n"; + + private int mProgram; + private int mvPositionHandle; + private int mvColorHandle; + + } +} + diff --git a/opengl/tests/testPauseResume/AndroidManifest.xml b/opengl/tests/testPauseResume/AndroidManifest.xml index 3e8e7e7..1879bc3 100644 --- a/opengl/tests/testPauseResume/AndroidManifest.xml +++ b/opengl/tests/testPauseResume/AndroidManifest.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2009, 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. -*/ +<!-- Copyright (C) 2009 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. --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" diff --git a/opengl/tests/testPauseResume/res/values/strings.xml b/opengl/tests/testPauseResume/res/values/strings.xml index 208fe15..b4c98fe 100644 --- a/opengl/tests/testPauseResume/res/values/strings.xml +++ b/opengl/tests/testPauseResume/res/values/strings.xml @@ -1,21 +1,17 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- -/* -** -** Copyright 2006, 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. -*/ +<!-- Copyright (C) 2006 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. --> <!-- This file contains resource definitions for displayed strings, allowing diff --git a/opengl/tests/testViewport/Android.mk b/opengl/tests/testViewport/Android.mk new file mode 100644 index 0000000..ab37809 --- /dev/null +++ b/opengl/tests/testViewport/Android.mk @@ -0,0 +1,26 @@ +######################################################################### +# OpenGL ES JNI sample +# This makefile builds both an activity and a shared library. +######################################################################### +ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestViewport + +# Set a specific SDK version so we can run on Froyo. + +LOCAL_SDK_VERSION := 8 + +include $(BUILD_PACKAGE) + +endif # TARGET_SIMULATOR diff --git a/opengl/tests/testViewport/AndroidManifest.xml b/opengl/tests/testViewport/AndroidManifest.xml new file mode 100644 index 0000000..ba178bb --- /dev/null +++ b/opengl/tests/testViewport/AndroidManifest.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2009 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.test"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <application + android:label="@string/test_activity"> + <activity android:name="TestActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testViewport/README b/opengl/tests/testViewport/README new file mode 100644 index 0000000..c06abc9 --- /dev/null +++ b/opengl/tests/testViewport/README @@ -0,0 +1,28 @@ +Repro steps: + +build, install and run the attached test program TestViewport.apk + +Run on Sapphire with Froyo. + +The program clears the screen to blue, then draws a full screen white quad that +is alligned to the screen. +(Therefore the whole screen should appear to be white.) + + +Note that screen is all white. + +Rotate screen 90 degrees. + +Expected: screen is still all white. + +Actual: screen is blue with offset white rectangle. + +This bug only happens on Sapphire, it works correctly on Passion. + +What happens: + +I think the bug is that the gl.glViewport() call in onSurfaceChanged() is +being ignored by the OpenGL driver. + +NOTE: If a gl.glViewport call is added at the beginning of the onDrawFrame() +call (which means it is called before every draw), the program runs correctly. diff --git a/opengl/tests/testViewport/res/values/strings.xml b/opengl/tests/testViewport/res/values/strings.xml new file mode 100644 index 0000000..c037a7c --- /dev/null +++ b/opengl/tests/testViewport/res/values/strings.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2006 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. +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="test_activity">Test Viewport</string> + +</resources> + diff --git a/opengl/tests/testViewport/src/com/android/test/TestActivity.java b/opengl/tests/testViewport/src/com/android/test/TestActivity.java new file mode 100644 index 0000000..cc7e450 --- /dev/null +++ b/opengl/tests/testViewport/src/com/android/test/TestActivity.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007 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.test; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +public class TestActivity extends Activity { + private final static String TAG = "TestActivity"; + TestView mView; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestView(getApplication()); + mView.setFocusableInTouchMode(true); + setContentView(mView); + } + + @Override + protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testViewport/src/com/android/test/TestView.java b/opengl/tests/testViewport/src/com/android/test/TestView.java new file mode 100644 index 0000000..23cc37d --- /dev/null +++ b/opengl/tests/testViewport/src/com/android/test/TestView.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2009 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.test; +/* + * 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.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.FloatBuffer; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class TestView extends GLSurfaceView { + TestView(Context context) { + super(context); + init(); + } + + public TestView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + private void init() { + setRenderer(new Renderer()); + setRenderMode(RENDERMODE_WHEN_DIRTY); + } + + /** A grid is a topologically rectangular array of vertices. + * + * The vertex and index data are held in VBO objects because on most + * GPUs VBO objects are the fastest way of rendering static vertex + * and index data. + * + */ + + private static class Grid { + // Size of vertex data elements in bytes: + final static int FLOAT_SIZE = 4; + final static int CHAR_SIZE = 2; + + // Vertex structure: + // float x, y, z; + + final static int VERTEX_SIZE = 3 * FLOAT_SIZE; + + private int mVertexBufferObjectId; + private int mElementBufferObjectId; + + // These buffers are used to hold the vertex and index data while + // constructing the grid. Once createBufferObjects() is called + // the buffers are nulled out to save memory. + + private ByteBuffer mVertexByteBuffer; + private FloatBuffer mVertexBuffer; + private CharBuffer mIndexBuffer; + + private int mW; + private int mH; + private int mIndexCount; + + public Grid(int w, int h) { + if (w < 0 || w >= 65536) { + throw new IllegalArgumentException("w"); + } + if (h < 0 || h >= 65536) { + throw new IllegalArgumentException("h"); + } + if (w * h >= 65536) { + throw new IllegalArgumentException("w * h >= 65536"); + } + + mW = w; + mH = h; + int size = w * h; + + mVertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * size) + .order(ByteOrder.nativeOrder()); + mVertexBuffer = mVertexByteBuffer.asFloatBuffer(); + + int quadW = mW - 1; + int quadH = mH - 1; + int quadCount = quadW * quadH; + int indexCount = quadCount * 6; + mIndexCount = indexCount; + mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount) + .order(ByteOrder.nativeOrder()).asCharBuffer(); + + /* + * Initialize triangle list mesh. + * + * [0]-----[ 1] ... + * | / | + * | / | + * | / | + * [w]-----[w+1] ... + * | | + * + */ + + { + int i = 0; + for (int y = 0; y < quadH; y++) { + for (int x = 0; x < quadW; x++) { + char a = (char) (y * mW + x); + char b = (char) (y * mW + x + 1); + char c = (char) ((y + 1) * mW + x); + char d = (char) ((y + 1) * mW + x + 1); + + mIndexBuffer.put(i++, a); + mIndexBuffer.put(i++, c); + mIndexBuffer.put(i++, b); + + mIndexBuffer.put(i++, b); + mIndexBuffer.put(i++, c); + mIndexBuffer.put(i++, d); + } + } + } + + } + + public void set(int i, int j, float x, float y, float z) { + if (i < 0 || i >= mW) { + throw new IllegalArgumentException("i"); + } + if (j < 0 || j >= mH) { + throw new IllegalArgumentException("j"); + } + + int index = mW * j + i; + + mVertexBuffer.position(index * VERTEX_SIZE / FLOAT_SIZE); + mVertexBuffer.put(x); + mVertexBuffer.put(y); + mVertexBuffer.put(z); + } + + public void createBufferObjects(GL gl) { + // Generate a the vertex and element buffer IDs + int[] vboIds = new int[2]; + GL11 gl11 = (GL11) gl; + gl11.glGenBuffers(2, vboIds, 0); + mVertexBufferObjectId = vboIds[0]; + mElementBufferObjectId = vboIds[1]; + + // Upload the vertex data + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId); + mVertexByteBuffer.position(0); + gl11.glBufferData(GL11.GL_ARRAY_BUFFER, mVertexByteBuffer.capacity(), mVertexByteBuffer, GL11.GL_STATIC_DRAW); + + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId); + mIndexBuffer.position(0); + gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity() * CHAR_SIZE, mIndexBuffer, GL11.GL_STATIC_DRAW); + + // We don't need the in-memory data any more + mVertexBuffer = null; + mVertexByteBuffer = null; + mIndexBuffer = null; + } + + public void draw(GL10 gl) { + GL11 gl11 = (GL11) gl; + + gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); + + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId); + gl11.glVertexPointer(3, GL10.GL_FLOAT, VERTEX_SIZE, 0); + + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId); + gl11.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, 0); + gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0); + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0); + } + } + + + private class Renderer implements GLSurfaceView.Renderer { + private static final String TAG = "Renderer"; + private Grid mGrid; + + public void onDrawFrame(GL10 gl) { + gl.glClearColor(0,0,1,1); + gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + mGrid.draw(gl); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + gl.glViewport(0, 0, width, height); + gl.glMatrixMode(GL11.GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrthof(0, width, height, 0, -1, 1); + gl.glMatrixMode(GL11.GL_MODELVIEW); + createGrid(gl, width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + } + + private void createGrid(GL10 gl, float w, float h) { + mGrid = new Grid(2, 2); + for (int j = 0; j < 2; j++) { + for (int i = 0; i < 2; i++) { + float x = w * i; + float y = h * j; + float z = 0.0f; + mGrid.set(i,j, x, y, z); + } + } + mGrid.createBufferObjects(gl); + } + } +} + diff --git a/opengl/tools/glgen/stubs/gles11/glGetString.java b/opengl/tools/glgen/stubs/gles11/glGetString.java index d44a6dd..b02a0d1 100644 --- a/opengl/tools/glgen/stubs/gles11/glGetString.java +++ b/opengl/tools/glgen/stubs/gles11/glGetString.java @@ -1,21 +1,21 @@ -/*
- * Copyright (C) 2009 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.
- */
-
- // C function const GLubyte * glGetString ( GLenum name )
-
- public static native String glGetString(
- int name
- );
+/* + * Copyright (C) 2009 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. + */ + + // C function const GLubyte * glGetString ( GLenum name ) + + public static native String glGetString( + int name + ); |