/**
**
** 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.
*/
#ifndef _PIXELFLINGER2_H_
#define _PIXELFLINGER2_H_
#define USE_LLVM_TEXTURE_SAMPLER 1
#define USE_LLVM_SCANLINE 1
#ifndef USE_LLVM_EXECUTIONENGINE
#define USE_LLVM_EXECUTIONENGINE 0 // 1 to use llvm::Execution, 0 to use libBCC, requires modifying makefile
#endif
#define USE_DUAL_THREAD 1
#define debug_printf printf
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#ifdef __arm__
#include <cutils/log.h>
#ifndef __location__
#define __HIERALLOC_STRING_0__(s) #s
#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
#endif
#undef assert
#define assert(EXPR) { do { if (!(EXPR)) {ALOGD("\n*\n*\n*\n* assert fail: '"#EXPR"' at "__location__"\n*\n*\n*"); exit(EXIT_FAILURE); } } while (false); }
#else // #ifdef __arm__
#ifndef ALOGD
#define ALOGD printf
#endif //#include <stdio.h>
#endif // #ifdef __arm__
#include "pixelflinger2/pixelflinger2_interface.h"
#include <string.h>
#ifndef MIN2
# define MIN2(a, b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX2
# define MAX2(a, b) ((a) > (b) ? (a) : (b))
#endif
namespace llvm
{
class LLVMContext;
};
#if !USE_LLVM_SCANLINE
typedef int BlendComp_t;
#endif
#if USE_DUAL_THREAD
#include <pthread.h>
#endif
typedef void (*ShaderFunction_t)(const void*,void*,const void*);
#define GGL_GET_CONTEXT(context, interface) GGLContext * context = (GGLContext *)interface;
#define GGL_GET_CONST_CONTEXT(context, interface) const GGLContext * context = \
(const GGLContext *)interface; (void)context;
struct GGLContext {
GGLInterface interface; // must be first member so that GGLContext * == GGLInterface *
GGLSurface frameSurface;
GGLSurface depthSurface;
GGLSurface stencilSurface;
llvm::LLVMContext * llvmCtx;
struct {
int depth; // assuming ieee 754 32 bit float and 32 bit 2's complement int; z_32
unsigned color; // clear value; rgba_8888
unsigned stencil; // s_8; repeated to clear 4 pixels at a time
} clearState;
gl_shader_program * CurrentProgram;
mutable GGLActiveStencil activeStencil; // after primitive assembly, call StencilSelect
GGLState state; // states affecting jit
#if USE_DUAL_THREAD
mutable struct Worker {
const GGLInterface * iface;
unsigned startY, endY, varyingCount;
VertexOutput bV, cV, bDx, cDx;
int width, height;
bool assignedWork; // only used by main; worker uses assignCond & quit
bool quit;
pthread_cond_t assignCond;
pthread_mutex_t assignLock; // held by worker execpt for during cond_wait assign
pthread_cond_t finishCond;
pthread_mutex_t finishLock; // held by main except for during cond_wait finish
pthread_t thread;
Worker() : assignedWork(false), quit(false), thread(0)
{
pthread_cond_init(&assignCond, NULL);
pthread_cond_init(&finishCond, NULL);
pthread_mutex_init(&assignLock, NULL);
pthread_mutex_init(&finishLock, NULL);
pthread_mutex_lock(&finishLock);
// actual thread is created later in raster.cpp
}
~Worker()
{
if (0 != thread)
{
pthread_mutex_lock(&assignLock);
quit = true;
pthread_cond_signal(&assignCond); // signal thread to quit
pthread_mutex_unlock(&assignLock);
pthread_join(thread, NULL);
}
pthread_mutex_unlock(&finishLock);
pthread_cond_destroy(&assignCond);
pthread_cond_destroy(&finishCond);
pthread_mutex_destroy(&assignLock);
pthread_mutex_destroy(&finishLock);
}
} worker;
#endif
// called by ShaderUse to set to proper rendering functions
void (* PickScanLine)(GGLInterface * iface);
void (* PickRaster)(GGLInterface * iface);
// viewport params are transformed so that Zw = Zd * f + n
// and Xw/Yw = x/y + Xd/Yd * w/h
struct {
VectorComp_t x, y, w, h, n, f;
} viewport; // should be moved into libAgl2
struct { // should be moved into libAgl2
unsigned enable :
1;
unsigned frontFace :
1; // GL_CW = 0, GL_CCW, actual value is GLenum - GL_CW
unsigned cullFace :
2; // GL_FRONT = 0, GL_BACK, GL_FRONT_AND_BACK, value = GLenum - GL_FRONT
} cullState;
};
#define _PF2_TEXTURE_DATA_NAME_ "gl_PF2TEXTURE_DATA" /* sampler data pointers used by LLVM */
#define _PF2_TEXTURE_DIMENSIONS_NAME_ "gl_PF2TEXTURE_DIMENSIONS" /* sampler dimensions used by LLVM */
void gglError(unsigned error); // not implmented, just an assert
void InitializeGGLState(GGLInterface * iface); // should be private
void UninitializeGGLState(GGLInterface * iface); // should be private
// they just set the function pointers
void InitializeBufferFunctions(GGLInterface * iface);
void InitializeRasterFunctions(GGLInterface * iface);
void InitializeScanLineFunctions(GGLInterface * iface);
void InitializeTextureFunctions(GGLInterface * iface);
void InitializeShaderFunctions(GGLInterface * iface); // set function pointers and create needed objects
void SetShaderVerifyFunctions(GGLInterface * iface); // called by state change functions
void DestroyShaderFunctions(GGLInterface * iface); // destroy needed objects
// actual gl_shader and gl_shader_program is created and destroyed by Shader(Program)Create/Delete,
#endif // #ifndef _PIXELFLINGER2_H_