diff options
Diffstat (limited to 'libs/hwui/tests')
-rw-r--r-- | libs/hwui/tests/Android.mk | 38 | ||||
-rw-r--r-- | libs/hwui/tests/TestContext.cpp | 65 | ||||
-rw-r--r-- | libs/hwui/tests/TestContext.h | 38 | ||||
-rw-r--r-- | libs/hwui/tests/main.cpp | 264 | ||||
-rw-r--r-- | libs/hwui/tests/nullegl.cpp | 160 | ||||
-rw-r--r-- | libs/hwui/tests/nullgles.cpp | 275 |
6 files changed, 719 insertions, 121 deletions
diff --git a/libs/hwui/tests/Android.mk b/libs/hwui/tests/Android.mk index 7bdce7f..b6f0baf 100644 --- a/libs/hwui/tests/Android.mk +++ b/libs/hwui/tests/Android.mk @@ -15,34 +15,9 @@ # local_target_dir := $(TARGET_OUT_DATA)/local/tmp -LOCAL_PATH:= $(call my-dir) +LOCAL_PATH:= $(call my-dir)/.. include $(CLEAR_VARS) -LOCAL_CFLAGS += -DUSE_OPENGL_RENDERER -DEGL_EGLEXT_PROTOTYPES -DGL_GLEXT_PROTOTYPES -LOCAL_CFLAGS += -Wno-unused-parameter -LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_VIEW -DLOG_TAG=\"OpenGLRenderer\" - -LOCAL_SRC_FILES:= \ - TestContext.cpp \ - main.cpp - -LOCAL_C_INCLUDES += \ - $(LOCAL_PATH)/.. \ - external/skia/src/core - -LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - libskia \ - libgui \ - libui \ - libhwui - -ifeq ($(WITH_MALLOC_LEAK_CHECK),true) - LOCAL_CFLAGS += -DMALLOC_LEAK_CHECK -endif - LOCAL_MODULE_PATH := $(local_target_dir) LOCAL_MODULE:= hwuitest LOCAL_MODULE_TAGS := tests @@ -50,7 +25,12 @@ LOCAL_MULTILIB := both LOCAL_MODULE_STEM_32 := hwuitest LOCAL_MODULE_STEM_64 := hwuitest64 -include external/stlport/libstlport.mk -include $(BUILD_EXECUTABLE) +HWUI_NULL_GPU := false + +include $(LOCAL_PATH)/Android.common.mk -include $(call all-makefiles-under,$(LOCAL_PATH)) +LOCAL_SRC_FILES += \ + tests/TestContext.cpp \ + tests/main.cpp + +include $(BUILD_EXECUTABLE) diff --git a/libs/hwui/tests/TestContext.cpp b/libs/hwui/tests/TestContext.cpp index 35e402d..542bbae 100644 --- a/libs/hwui/tests/TestContext.cpp +++ b/libs/hwui/tests/TestContext.cpp @@ -16,30 +16,59 @@ #include "TestContext.h" -#include <gui/ISurfaceComposer.h> -#include <gui/SurfaceComposerClient.h> +namespace android { +namespace uirenderer { +namespace test { -using namespace android; +static const int IDENT_DISPLAYEVENT = 1; -DisplayInfo gDisplay; -sp<SurfaceComposerClient> gSession; - -void createTestEnvironment() { - gSession = new SurfaceComposerClient(); +static DisplayInfo getBuiltInDisplay() { + DisplayInfo display; sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); - status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &gDisplay); + ISurfaceComposer::eDisplayIdMain)); + status_t status = SurfaceComposerClient::getDisplayInfo(dtoken, &display); LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n"); + return display; +} + +android::DisplayInfo gDisplay = getBuiltInDisplay(); + +TestContext::TestContext() { + mLooper = new Looper(true); + mSurfaceComposerClient = new SurfaceComposerClient(); + mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT, + Looper::EVENT_INPUT, nullptr, nullptr); } -sp<SurfaceControl> createWindow(int width, int height) { - sp<SurfaceControl> control = gSession->createSurface(String8("HwuiTest"), - width, height, PIXEL_FORMAT_RGBX_8888); +TestContext::~TestContext() {} + +sp<Surface> TestContext::surface() { + if (!mSurfaceControl.get()) { + mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"), + gDisplay.w, gDisplay.h, PIXEL_FORMAT_RGBX_8888); - SurfaceComposerClient::openGlobalTransaction(); - control->setLayer(0x7FFFFFF); - control->show(); - SurfaceComposerClient::closeGlobalTransaction(); + SurfaceComposerClient::openGlobalTransaction(); + mSurfaceControl->setLayer(0x7FFFFFF); + mSurfaceControl->show(); + SurfaceComposerClient::closeGlobalTransaction(); + } - return control; + return mSurfaceControl->getSurface(); } + +void TestContext::waitForVsync() { + // Request vsync + mDisplayEventReceiver.requestNextVsync(); + + // Wait + mLooper->pollOnce(-1); + + // Drain it + DisplayEventReceiver::Event buf[100]; + while (mDisplayEventReceiver.getEvents(buf, 100) > 0) { } +} + +} // namespace test +} // namespace uirenderer +} // namespace android + diff --git a/libs/hwui/tests/TestContext.h b/libs/hwui/tests/TestContext.h index 8a5d530..7b30fc1 100644 --- a/libs/hwui/tests/TestContext.h +++ b/libs/hwui/tests/TestContext.h @@ -17,17 +17,39 @@ #ifndef TESTCONTEXT_H #define TESTCONTEXT_H -#include <ui/DisplayInfo.h> +#include <gui/DisplayEventReceiver.h> +#include <gui/ISurfaceComposer.h> +#include <gui/SurfaceComposerClient.h> #include <gui/SurfaceControl.h> +#include <gui/Surface.h> +#include <ui/DisplayInfo.h> +#include <utils/Looper.h> + +namespace android { +namespace uirenderer { +namespace test { + +extern DisplayInfo gDisplay; +#define dp(x) ((x) * android::uirenderer::test::gDisplay.density) + +class TestContext { +public: + TestContext(); + ~TestContext(); + + sp<Surface> surface(); -extern android::DisplayInfo gDisplay; -#define dp(x) ((x) * gDisplay.density) + void waitForVsync(); -// Initializes all the static globals that are shared across all contexts -// such as display info -void createTestEnvironment(); +private: + sp<SurfaceComposerClient> mSurfaceComposerClient; + sp<SurfaceControl> mSurfaceControl; + DisplayEventReceiver mDisplayEventReceiver; + sp<Looper> mLooper; +}; -// Defaults to fullscreen -android::sp<android::SurfaceControl> createWindow(int width = -1, int height = -1); +} // namespace test +} // namespace uirenderer +} // namespace android #endif diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index 2d99e9f..61ad082 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -21,111 +21,243 @@ #include <ui/PixelFormat.h> #include <AnimationContext.h> -#include <DisplayListRenderer.h> +#include <DisplayListCanvas.h> #include <RenderNode.h> #include <renderthread/RenderProxy.h> +#include <renderthread/RenderTask.h> #include "TestContext.h" using namespace android; using namespace android::uirenderer; using namespace android::uirenderer::renderthread; +using namespace android::uirenderer::test; class ContextFactory : public IContextFactory { public: - virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { + virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) override { return new AnimationContext(clock); } }; -static DisplayListRenderer* startRecording(RenderNode* node) { - DisplayListRenderer* renderer = new DisplayListRenderer(); - renderer->setViewport(node->getWidth(), node->getHeight()); - renderer->prepare(false); +static DisplayListCanvas* startRecording(RenderNode* node) { + DisplayListCanvas* renderer = new DisplayListCanvas(); + renderer->setViewport(node->stagingProperties().getWidth(), + node->stagingProperties().getHeight()); + renderer->prepare(); return renderer; } -static void endRecording(DisplayListRenderer* renderer, RenderNode* node) { +static void endRecording(DisplayListCanvas* renderer, RenderNode* node) { renderer->finish(); node->setStagingDisplayList(renderer->finishRecording()); delete renderer; } -sp<RenderNode> createCard(int x, int y, int width, int height) { - sp<RenderNode> node = new RenderNode(); - node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height); - node->mutateStagingProperties().setElevation(dp(16)); - node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1); - node->mutateStagingProperties().mutableOutline().setShouldClip(true); - node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z); +class TreeContentAnimation { +public: + virtual ~TreeContentAnimation() {} + virtual int getFrameCount() { return 150; } + virtual void createContent(int width, int height, DisplayListCanvas* renderer) = 0; + virtual void doFrame(int frameNr) = 0; - DisplayListRenderer* renderer = startRecording(node.get()); - renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode); - endRecording(renderer, node.get()); + template <class T> + static void run() { + T animation; - return node; -} + TestContext testContext; -int main(int argc, char* argv[]) { - createTestEnvironment(); - - // create the native surface - const int width = gDisplay.w; - const int height = gDisplay.h; - sp<SurfaceControl> control = createWindow(width, height); - sp<Surface> surface = control->getSurface(); - - RenderNode* rootNode = new RenderNode(); - rootNode->incStrong(0); - rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height); - rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); - rootNode->mutateStagingProperties().setClipToBounds(false); - rootNode->setPropertyFieldsDirty(RenderNode::GENERIC); - - ContextFactory factory; - RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); - proxy->loadSystemProperties(); - proxy->initialize(surface); - float lightX = width / 2.0; - proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)}, - dp(800.0f), 255 * 0.075, 255 * 0.15); - - android::uirenderer::Rect DUMMY; + // create the native surface + const int width = gDisplay.w; + const int height = gDisplay.h; + sp<Surface> surface = testContext.surface(); - std::vector< sp<RenderNode> > cards; + RenderNode* rootNode = new RenderNode(); + rootNode->incStrong(nullptr); + rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height); + rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); + rootNode->mutateStagingProperties().setClipToBounds(false); + rootNode->setPropertyFieldsDirty(RenderNode::GENERIC); + + ContextFactory factory; + std::unique_ptr<RenderProxy> proxy(new RenderProxy(false, rootNode, &factory)); + proxy->loadSystemProperties(); + proxy->initialize(surface); + float lightX = width / 2.0; + proxy->setup(width, height, (Vector3){lightX, dp(-200.0f), dp(800.0f)}, + dp(800.0f), 255 * 0.075, 255 * 0.15); + + android::uirenderer::Rect DUMMY; + + DisplayListCanvas* renderer = startRecording(rootNode); + animation.createContent(width, height, renderer); + endRecording(renderer, rootNode); - DisplayListRenderer* renderer = startRecording(rootNode); - renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); - renderer->insertReorderBarrier(true); + for (int i = 0; i < animation.getFrameCount(); i++) { +#if !HWUI_NULL_GPU + testContext.waitForVsync(); +#endif - for (int x = dp(16); x < (width - dp(116)); x += dp(116)) { - for (int y = dp(16); y < (height - dp(116)); y += dp(116)) { - sp<RenderNode> card = createCard(x, y, dp(100), dp(100)); - renderer->drawRenderNode(card.get(), DUMMY, 0); - cards.push_back(card); + ATRACE_NAME("UI-Draw Frame"); + animation.doFrame(i); + proxy->syncAndDrawFrame(); } + + rootNode->decStrong(nullptr); } +}; + +class ShadowGridAnimation : public TreeContentAnimation { +public: + std::vector< sp<RenderNode> > cards; + void createContent(int width, int height, DisplayListCanvas* renderer) override { + android::uirenderer::Rect DUMMY; + + renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); + renderer->insertReorderBarrier(true); - renderer->insertReorderBarrier(false); - endRecording(renderer, rootNode); + for (int x = dp(16); x < (width - dp(116)); x += dp(116)) { + for (int y = dp(16); y < (height - dp(116)); y += dp(116)) { + sp<RenderNode> card = createCard(x, y, dp(100), dp(100)); + renderer->drawRenderNode(card.get(), DUMMY, 0); + cards.push_back(card); + } + } - for (int i = 0; i < 150; i++) { - ATRACE_NAME("UI-Draw Frame"); - for (int ci = 0; ci < cards.size(); ci++) { - cards[ci]->mutateStagingProperties().setTranslationX(i); - cards[ci]->mutateStagingProperties().setTranslationY(i); + renderer->insertReorderBarrier(false); + } + void doFrame(int frameNr) override { + for (size_t ci = 0; ci < cards.size(); ci++) { + cards[ci]->mutateStagingProperties().setTranslationX(frameNr); + cards[ci]->mutateStagingProperties().setTranslationY(frameNr); cards[ci]->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); } - nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); - proxy->syncAndDrawFrame(frameTimeNs, 0, gDisplay.density); - usleep(12000); } +private: + sp<RenderNode> createCard(int x, int y, int width, int height) { + sp<RenderNode> node = new RenderNode(); + node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height); + node->mutateStagingProperties().setElevation(dp(16)); + node->mutateStagingProperties().mutableOutline().setRoundRect(0, 0, width, height, dp(10), 1); + node->mutateStagingProperties().mutableOutline().setShouldClip(true); + node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y | RenderNode::Z); + + DisplayListCanvas* renderer = startRecording(node.get()); + renderer->drawColor(0xFFEEEEEE, SkXfermode::kSrcOver_Mode); + endRecording(renderer, node.get()); + return node; + } +}; + +class RectGridAnimation : public TreeContentAnimation { +public: + sp<RenderNode> card; + void createContent(int width, int height, DisplayListCanvas* renderer) override { + android::uirenderer::Rect DUMMY; - sleep(5); + renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); + renderer->insertReorderBarrier(true); - delete proxy; - rootNode->decStrong(0); + card = createCard(40, 40, 200, 200); + renderer->drawRenderNode(card.get(), DUMMY, 0); + + renderer->insertReorderBarrier(false); + } + void doFrame(int frameNr) override { + card->mutateStagingProperties().setTranslationX(frameNr); + card->mutateStagingProperties().setTranslationY(frameNr); + card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); + } +private: + sp<RenderNode> createCard(int x, int y, int width, int height) { + sp<RenderNode> node = new RenderNode(); + node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height); + node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); + + DisplayListCanvas* renderer = startRecording(node.get()); + renderer->drawColor(0xFFFF00FF, SkXfermode::kSrcOver_Mode); + + float rects[width * height]; + int index = 0; + for (int xOffset = 0; xOffset < width; xOffset+=2) { + for (int yOffset = 0; yOffset < height; yOffset+=2) { + rects[index++] = xOffset; + rects[index++] = yOffset; + rects[index++] = xOffset + 1; + rects[index++] = yOffset + 1; + } + } + int count = width * height; + SkPaint paint; + paint.setColor(0xff00ffff); + renderer->drawRects(rects, count, &paint); + + endRecording(renderer, node.get()); + return node; + } +}; + +class OvalAnimation : public TreeContentAnimation { +public: + sp<RenderNode> card; + void createContent(int width, int height, DisplayListCanvas* renderer) override { + android::uirenderer::Rect DUMMY; + + renderer->drawColor(0xFFFFFFFF, SkXfermode::kSrcOver_Mode); + renderer->insertReorderBarrier(true); + + card = createCard(40, 40, 400, 400); + renderer->drawRenderNode(card.get(), DUMMY, 0); + + renderer->insertReorderBarrier(false); + } + + void doFrame(int frameNr) override { + card->mutateStagingProperties().setTranslationX(frameNr); + card->mutateStagingProperties().setTranslationY(frameNr); + card->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); + } +private: + sp<RenderNode> createCard(int x, int y, int width, int height) { + sp<RenderNode> node = new RenderNode(); + node->mutateStagingProperties().setLeftTopRightBottom(x, y, x + width, y + height); + node->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); + + DisplayListCanvas* renderer = startRecording(node.get()); + + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(0xFF000000); + renderer->drawOval(0, 0, width, height, paint); + + endRecording(renderer, node.get()); + return node; + } +}; + +struct cstr_cmp { + bool operator()(const char *a, const char *b) const { + return std::strcmp(a, b) < 0; + } +}; + +typedef void (*testProc)(); + +std::map<const char*, testProc, cstr_cmp> gTestMap { + {"shadowgrid", TreeContentAnimation::run<ShadowGridAnimation>}, + {"rectgrid", TreeContentAnimation::run<RectGridAnimation> }, + {"oval", TreeContentAnimation::run<OvalAnimation> }, +}; + +int main(int argc, char* argv[]) { + const char* testName = argc > 1 ? argv[1] : "shadowgrid"; + testProc proc = gTestMap[testName]; + if(!proc) { + printf("Error: couldn't find test %s\n", testName); + return 1; + } + proc(); printf("Success!\n"); return 0; } diff --git a/libs/hwui/tests/nullegl.cpp b/libs/hwui/tests/nullegl.cpp new file mode 100644 index 0000000..b6cc2f2 --- /dev/null +++ b/libs/hwui/tests/nullegl.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015 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 <EGL/egl.h> +#include <EGL/eglext.h> + +#include <pthread.h> +#include <stdlib.h> +#include <string.h> + +static EGLDisplay gDisplay = (EGLDisplay) 1; + +typedef struct { + EGLSurface surface; + EGLContext context; +} ThreadState; + +static pthread_key_t ThreadStateKey; +static pthread_once_t ThreadStateSetupOnce = PTHREAD_ONCE_INIT; + +static void destroyThreadState(void* state) { + free(state); +} + +static void makeThreadState() { + pthread_key_create(&ThreadStateKey, destroyThreadState); +} + +ThreadState* getThreadState() { + ThreadState* ptr; + pthread_once(&ThreadStateSetupOnce, makeThreadState); + if ((ptr = (ThreadState*) pthread_getspecific(ThreadStateKey)) == NULL) { + ptr = (ThreadState*) calloc(1, sizeof(ThreadState)); + ptr->context = EGL_NO_CONTEXT; + ptr->surface = EGL_NO_SURFACE; + pthread_setspecific(ThreadStateKey, ptr); + } + return ptr; +} + +EGLint eglGetError(void) { + return EGL_SUCCESS; +} + +EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) { + return gDisplay; +} + +EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { + return EGL_TRUE; +} + +EGLBoolean eglTerminate(EGLDisplay dpy) { + return EGL_TRUE; +} + +const char * eglQueryString(EGLDisplay dpy, EGLint name) { + return ""; +} + +EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, + EGLConfig *configs, EGLint config_size, + EGLint *num_config) { + memset(configs, 9, sizeof(EGLConfig) * config_size); + *num_config = config_size; + return EGL_TRUE; +} + +EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, + EGLNativeWindowType win, + const EGLint *attrib_list) { + return (EGLSurface) malloc(sizeof(void*)); +} + +EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, + const EGLint *attrib_list) { + return (EGLSurface) malloc(sizeof(void*)); +} + +EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { + free(surface); + return EGL_TRUE; +} + +EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint *value) { + *value = 1000; + return EGL_TRUE; +} + +EGLBoolean eglReleaseThread(void) { + return EGL_TRUE; +} + +EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, + EGLint attribute, EGLint value) { + return EGL_TRUE; +} + +EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { + return EGL_TRUE; +} + +EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, + EGLContext share_context, + const EGLint *attrib_list) { + return (EGLContext) malloc(sizeof(void*)); +} +EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { + free(ctx); + return EGL_TRUE; +} + +EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, + EGLSurface read, EGLContext ctx) { + ThreadState* state = getThreadState(); + state->surface = draw; + state->context = ctx; + return EGL_TRUE; +} + +EGLContext eglGetCurrentContext(void) { + return getThreadState()->context; +} + +EGLSurface eglGetCurrentSurface(EGLint readdraw) { + return getThreadState()->surface; +} + +EGLDisplay eglGetCurrentDisplay(void) { + return gDisplay; +} + +EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { + return EGL_TRUE; +} + +EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) { + return (EGLImageKHR) malloc(sizeof(EGLImageKHR)); +} + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) { + free(image); + return EGL_TRUE; +} + +void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {} diff --git a/libs/hwui/tests/nullgles.cpp b/libs/hwui/tests/nullgles.cpp new file mode 100644 index 0000000..8ca7598 --- /dev/null +++ b/libs/hwui/tests/nullgles.cpp @@ -0,0 +1,275 @@ +/* + * Copyright(C) 2015 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 <GLES3/gl3.h> +#include <GLES2/gl2ext.h> + +#include <stdlib.h> +#include <string.h> + +struct { + GLboolean scissorEnabled; +} gState; + +void glGenCommon(GLsizei n, GLuint *buffers) { + static GLuint nextId = 0; + int i; + for(i = 0; i < n; i++) { + buffers[i] = ++nextId; + } +} + +void glGenBuffers(GLsizei n, GLuint *buffers) { + glGenCommon(n, buffers); +} + +void glGenFramebuffers(GLsizei n, GLuint *framebuffers) { + glGenCommon(n, framebuffers); +} + +void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { + glGenCommon(n, renderbuffers); +} + +void glGenTextures(GLsizei n, GLuint *textures) { + glGenCommon(n, textures); +} + +GLuint glCreateProgram(void) { + static GLuint nextProgram = 0; + return ++nextProgram; +} + +GLuint glCreateShader(GLenum type) { + static GLuint nextShader = 0; + return ++nextShader; +} + +void glGetProgramiv(GLuint program, GLenum pname, GLint *params) { + switch (pname) { + case GL_DELETE_STATUS: + case GL_LINK_STATUS: + case GL_VALIDATE_STATUS: + *params = GL_TRUE; + break; + case GL_INFO_LOG_LENGTH: + *params = 16; + break; + } +} + +void glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { + *length = snprintf(infoLog, bufSize, "success"); + if (*length >= bufSize) { + *length = bufSize - 1; + } +} + +void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) { + switch (pname) { + case GL_COMPILE_STATUS: + case GL_DELETE_STATUS: + *params = GL_TRUE; + } +} + +void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) { + *length = snprintf(infoLog, bufSize, "success"); + if (*length >= bufSize) { + *length = bufSize - 1; + } +} + +void setBooleanState(GLenum cap, GLboolean value) { + switch (cap) { + case GL_SCISSOR_TEST: + gState.scissorEnabled = value; + break; + } +} + +void glEnable(GLenum cap) { + setBooleanState(cap, GL_TRUE); +} + +void glDisable(GLenum cap) { + setBooleanState(cap, GL_FALSE); +} + +GLboolean glIsEnabled(GLenum cap) { + switch (cap) { + case GL_SCISSOR_TEST: + return gState.scissorEnabled; + default: + return GL_FALSE; + } +} + +void glGetIntegerv(GLenum pname, GLint *data) { + switch (pname) { + case GL_MAX_TEXTURE_SIZE: + *data = 2048; + break; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + *data = 4; + break; + default: + *data = 0; + } +} + +const char* getString(GLenum name) { + switch (name) { + case GL_VENDOR: + return "android"; + case GL_RENDERER: + return "null"; + case GL_VERSION: + return "OpenGL ES 2.0 rev1"; + case GL_SHADING_LANGUAGE_VERSION: + return "OpenGL ES GLSL ES 2.0 rev1"; + case GL_EXTENSIONS: + default: + return ""; + } +} + +const GLubyte* glGetString(GLenum name) { + return (GLubyte*) getString(name); +} + +void glActiveTexture(GLenum texture) {} +void glAttachShader(GLuint program, GLuint shader) {} +void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name) {} +void glBindBuffer(GLenum target, GLuint buffer) {} +void glBindFramebuffer(GLenum target, GLuint framebuffer) {} +void glBindRenderbuffer(GLenum target, GLuint renderbuffer) {} +void glBindTexture(GLenum target, GLuint texture) {} +void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {} +void glBlendEquation(GLenum mode) {} +void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {} +void glBlendFunc(GLenum sfactor, GLenum dfactor) {} +void glBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) {} +void glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage) {} +void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void *data) {} +void glClear(GLbitfield mask) {} +void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {} +void glClearDepthf(GLfloat d) {} +void glClearStencil(GLint s) {} +void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {} +void glCompileShader(GLuint shader) {} +void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) {} +void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) {} +void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {} +void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {} +void glCullFace(GLenum mode) {} +void glDeleteBuffers(GLsizei n, const GLuint *buffers) {} +void glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers) {} +void glDeleteProgram(GLuint program) {} +void glDeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) {} +void glDeleteShader(GLuint shader) {} +void glDeleteTextures(GLsizei n, const GLuint *textures) {} +void glDepthFunc(GLenum func) {} +void glDepthMask(GLboolean flag) {} +void glDepthRangef(GLfloat n, GLfloat f) {} +void glDetachShader(GLuint program, GLuint shader) {} +void glDisableVertexAttribArray(GLuint index) {} +void glDrawArrays(GLenum mode, GLint first, GLsizei count) {} +void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) {} +void glEnableVertexAttribArray(GLuint index) {} +void glFinish(void) {} +void glFlush(void) {} +void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) {} +void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {} +void glFrontFace(GLenum mode) {} +void glGenerateMipmap(GLenum target) {} +GLint glGetAttribLocation(GLuint program, const GLchar *name) { return 1; } +GLenum glGetError(void) { return GL_NO_ERROR; } +GLint glGetUniformLocation(GLuint program, const GLchar *name) { return 2; } +void glHint(GLenum target, GLenum mode) {} +void glLineWidth(GLfloat width) {} +void glLinkProgram(GLuint program) {} +void glPixelStorei(GLenum pname, GLint param) {} +void glPolygonOffset(GLfloat factor, GLfloat units) {} +void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) {} +void glReleaseShaderCompiler(void) {} +void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {} +void glSampleCoverage(GLfloat value, GLboolean invert) {} +void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {} +void glShaderBinary(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length) {} +void glShaderSource(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length) {} +void glStencilFunc(GLenum func, GLint ref, GLuint mask) {} +void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {} +void glStencilMask(GLuint mask) {} +void glStencilMaskSeparate(GLenum face, GLuint mask) {} +void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {} +void glStencilOpSeparate(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) {} +void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) {} +void glTexParameterf(GLenum target, GLenum pname, GLfloat param) {} +void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) {} +void glTexParameteri(GLenum target, GLenum pname, GLint param) {} +void glTexParameteriv(GLenum target, GLenum pname, const GLint *params) {} +void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) {} +void glUniform1f(GLint location, GLfloat v0) {} +void glUniform1fv(GLint location, GLsizei count, const GLfloat *value) {} +void glUniform1i(GLint location, GLint v0) {} +void glUniform1iv(GLint location, GLsizei count, const GLint *value) {} +void glUniform2f(GLint location, GLfloat v0, GLfloat v1) {} +void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) {} +void glUniform2i(GLint location, GLint v0, GLint v1) {} +void glUniform2iv(GLint location, GLsizei count, const GLint *value) {} +void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {} +void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) {} +void glUniform3i(GLint location, GLint v0, GLint v1, GLint v2) {} +void glUniform3iv(GLint location, GLsizei count, const GLint *value) {} +void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) {} +void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) {} +void glUniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) {} +void glUniform4iv(GLint location, GLsizei count, const GLint *value) {} +void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {} +void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {} +void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) {} +void glUseProgram(GLuint program) {} +void glValidateProgram(GLuint program) {} +void glVertexAttrib1f(GLuint index, GLfloat x) {} +void glVertexAttrib1fv(GLuint index, const GLfloat *v) {} +void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) {} +void glVertexAttrib2fv(GLuint index, const GLfloat *v) {} +void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) {} +void glVertexAttrib3fv(GLuint index, const GLfloat *v) {} +void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {} +void glVertexAttrib4fv(GLuint index, const GLfloat *v) {} +void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer) {} +void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) {} + + +// gles2 ext +void glInsertEventMarkerEXT(GLsizei length, const GLchar *marker) {} +void glPushGroupMarkerEXT(GLsizei length, const GLchar *marker) {} +void glPopGroupMarkerEXT(void) {} +void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) {} +void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {} +void glEndTilingQCOM(GLbitfield preserveMask) {} +void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) {} + +// GLES3 +void* glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { + return 0; +} + +GLboolean glUnmapBuffer(GLenum target) { + return GL_FALSE; +} |