1
0
Fork 0
mutter-performance-source/examples/android/hello/jni/main.c
2011-05-17 15:24:54 +01:00

188 lines
4.7 KiB
C

/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2011 Intel Corporation
*
* 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 is derived from the "native-activity" sample of the android NDK
* r5b. The coding style has been adapted to the code style most commonly found
* in glib/gobject based projects.
*/
#include <android_native_app_glue.h>
#include <glib.h>
#include <glib-android/glib-android.h>
#include <cogl/cogl.h>
typedef struct
{
struct android_app* app;
CoglContext *context;
CoglPrimitive *triangle;
CoglFramebuffer *fb;
} TestData;
static int test_init (TestData* data)
{
CoglOnscreen *onscreen;
GError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0x80},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
cogl_android_set_native_window (data->app->window);
data->context = cogl_context_new (NULL, &error);
if (!data->context)
{
g_critical ("Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (data->context, 320, 420);
/* Eventually there will be an implicit allocate on first use so this
* will become optional... */
data->fb = COGL_FRAMEBUFFER (onscreen);
if (!cogl_framebuffer_allocate (data->fb, &error))
{
if (error)
g_critical ("Failed to allocate framebuffer: %s\n", error->message);
else
g_critical ("Failed to allocate framebuffer");
return 1;
}
cogl_onscreen_show (onscreen);
cogl_push_framebuffer (data->fb);
data->triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
return 0;
}
static test_draw_frame_and_swap (TestData *data)
{
if (data->context)
{
cogl_primitive_draw (data->triangle);
cogl_framebuffer_swap_buffers (data->fb);
}
}
static void
test_fini (TestData *data)
{
if (data->fb)
{
cogl_object_unref (data->triangle);
cogl_object_unref (data->fb);
cogl_object_unref (data->context);
data->triangle = NULL;
data->fb = NULL;
data->context = NULL;
}
}
/**
* Process the next main command.
*/
static void
test_handle_cmd (struct android_app* app,
int32_t cmd)
{
TestData *data = (TestData *) app->userData;
switch (cmd)
{
case APP_CMD_INIT_WINDOW:
/* The window is being shown, get it ready */
g_message ("command: INIT_WINDOW");
if (data->app->window != NULL)
{
test_init (data);
test_draw_frame_and_swap (data);
}
break;
case APP_CMD_TERM_WINDOW:
/* The window is being hidden or closed, clean it up */
g_message ("command: TERM_WINDOW");
test_fini (data);
break;
case APP_CMD_GAINED_FOCUS:
g_message ("command: GAINED_FOCUS");
break;
case APP_CMD_LOST_FOCUS:
/* When our app loses focus, we stop monitoring the accelerometer.
* This is to avoid consuming battery while not being used. */
g_message ("command: LOST_FOCUS");
test_draw_frame_and_swap (data);
break;
}
}
/**
* This is the main entry point of a native application that is using
* android_native_app_glue. It runs in its own thread, with its own
* event loop for receiving input events and doing other things.
*/
void
android_main (struct android_app* application)
{
TestData data;
/* Make sure glue isn't stripped */
app_dummy ();
g_android_init (NULL, NULL, G_ANDROID_INIT_FLAG_LOG_HANDLER);
memset (&data, 0, sizeof (TestData));
application->userData = &data;
application->onAppCmd = test_handle_cmd;
data.app = application;
while (1)
{
int events;
struct android_poll_source* source;
while ((ALooper_pollAll (0, NULL, &events, (void**)&source)) >= 0)
{
/* Process this event */
if (source != NULL)
source->process (application, source);
/* Check if we are exiting */
if (application->destroyRequested != 0)
{
test_fini (&data);
return;
}
}
test_draw_frame_and_swap (&data);
}
}