summaryrefslogtreecommitdiffstats
path: root/libpixelflinger/include/private/pixelflinger/ggl_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'libpixelflinger/include/private/pixelflinger/ggl_context.h')
-rw-r--r--libpixelflinger/include/private/pixelflinger/ggl_context.h565
1 files changed, 565 insertions, 0 deletions
diff --git a/libpixelflinger/include/private/pixelflinger/ggl_context.h b/libpixelflinger/include/private/pixelflinger/ggl_context.h
new file mode 100644
index 0000000..d43655c
--- /dev/null
+++ b/libpixelflinger/include/private/pixelflinger/ggl_context.h
@@ -0,0 +1,565 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_GGL_CONTEXT_H
+#define ANDROID_GGL_CONTEXT_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <sys/types.h>
+#include <endian.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <private/pixelflinger/ggl_fixed.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
+ return v;
+}
+inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
+ return v;
+}
+
+#else
+
+inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) {
+#if defined(__mips__) && __mips==32 && __mips_isa_rev>=2
+ uint32_t r;
+ __asm__("wsbh %0, %1;"
+ "rotr %0, %0, 16"
+ : "=r" (r)
+ : "r" (v)
+ );
+ return r;
+#else
+ return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+#endif
+}
+inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) {
+#if defined(__mips__) && __mips==32 && __mips_isa_rev>=2
+ uint32_t r;
+ __asm__("wsbh %0, %1;"
+ "rotr %0, %0, 16"
+ : "=r" (r)
+ : "r" (v)
+ );
+ return r;
+#else
+ return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00);
+#endif
+}
+
+#endif
+
+// ----------------------------------------------------------------------------
+
+const int GGL_DITHER_BITS = 6; // dither weights stored on 6 bits
+const int GGL_DITHER_ORDER_SHIFT= 3;
+const int GGL_DITHER_ORDER = (1<<GGL_DITHER_ORDER_SHIFT);
+const int GGL_DITHER_SIZE = GGL_DITHER_ORDER * GGL_DITHER_ORDER;
+const int GGL_DITHER_MASK = GGL_DITHER_ORDER-1;
+
+// ----------------------------------------------------------------------------
+
+const int GGL_SUBPIXEL_BITS = 4;
+
+// TRI_FRACTION_BITS defines the number of bits we want to use
+// for the sub-pixel coordinates during the edge stepping, the
+// value shouldn't be more than 7, or bad things are going to
+// happen when drawing large triangles (8 doesn't work because
+// 32 bit muls will loose the sign bit)
+
+#define TRI_FRACTION_BITS (GGL_SUBPIXEL_BITS)
+#define TRI_ONE (1 << TRI_FRACTION_BITS)
+#define TRI_HALF (1 << (TRI_FRACTION_BITS-1))
+#define TRI_FROM_INT(x) ((x) << TRI_FRACTION_BITS)
+#define TRI_FRAC(x) ((x) & (TRI_ONE-1))
+#define TRI_FLOOR(x) ((x) & ~(TRI_ONE-1))
+#define TRI_CEIL(x) (((x) + (TRI_ONE-1)) & ~(TRI_ONE-1))
+#define TRI_ROUND(x) (((x) + TRI_HALF ) & ~(TRI_ONE-1))
+
+#define TRI_ROUDNING (1 << (16 - TRI_FRACTION_BITS - 1))
+#define TRI_FROM_FIXED(x) (((x)+TRI_ROUDNING) >> (16-TRI_FRACTION_BITS))
+
+#define TRI_SNAP_NEXT_HALF(x) (TRI_CEIL((x)+TRI_HALF) - TRI_HALF)
+#define TRI_SNAP_PREV_HALF(x) (TRI_CEIL((x)-TRI_HALF) - TRI_HALF)
+
+// ----------------------------------------------------------------------------
+
+const int GGL_COLOR_BITS = 24;
+
+// To maintain 8-bits color chanels, with a maximum GGLSurface
+// size of 4096 and GGL_SUBPIXEL_BITS=4, we need 8 + 12 + 4 = 24 bits
+// for encoding the color iterators
+
+inline GGLcolor gglFixedToIteratedColor(GGLfixed c) {
+ return (c << 8) - c;
+}
+
+// ----------------------------------------------------------------------------
+
+template<bool> struct CTA;
+template<> struct CTA<true> { };
+
+#define GGL_CONTEXT(con, c) context_t *con = static_cast<context_t *>(c)
+#define GGL_OFFSETOF(field) uintptr_t(&(((context_t*)0)->field))
+#define GGL_INIT_PROC(p, f) p.f = ggl_ ## f;
+#define GGL_BETWEEN(x, L, H) (uint32_t((x)-(L)) <= ((H)-(L)))
+
+#define ggl_likely(x) __builtin_expect(!!(x), 1)
+#define ggl_unlikely(x) __builtin_expect(!!(x), 0)
+
+const int GGL_TEXTURE_UNIT_COUNT = 2;
+const int GGL_TMU_STATE = 0x00000001;
+const int GGL_CB_STATE = 0x00000002;
+const int GGL_PIXEL_PIPELINE_STATE = 0x00000004;
+
+// ----------------------------------------------------------------------------
+
+#define GGL_RESERVE_NEEDS(name, l, s) \
+ const uint32_t GGL_NEEDS_##name##_MASK = (((1LU<<(s))-1)<<l); \
+ const uint32_t GGL_NEEDS_##name##_SHIFT = (l);
+
+#define GGL_BUILD_NEEDS(val, name) \
+ (((val)<<(GGL_NEEDS_##name##_SHIFT)) & GGL_NEEDS_##name##_MASK)
+
+#define GGL_READ_NEEDS(name, n) \
+ (uint32_t(n & GGL_NEEDS_##name##_MASK) >> GGL_NEEDS_##name##_SHIFT)
+
+#define GGL_NEED_MASK(name) (uint32_t(GGL_NEEDS_##name##_MASK))
+#define GGL_NEED(name, val) GGL_BUILD_NEEDS(val, name)
+
+GGL_RESERVE_NEEDS( CB_FORMAT, 0, 6 )
+GGL_RESERVE_NEEDS( SHADE, 6, 1 )
+GGL_RESERVE_NEEDS( W, 7, 1 )
+GGL_RESERVE_NEEDS( BLEND_SRC, 8, 4 )
+GGL_RESERVE_NEEDS( BLEND_DST, 12, 4 )
+GGL_RESERVE_NEEDS( BLEND_SRCA, 16, 4 )
+GGL_RESERVE_NEEDS( BLEND_DSTA, 20, 4 )
+GGL_RESERVE_NEEDS( LOGIC_OP, 24, 4 )
+GGL_RESERVE_NEEDS( MASK_ARGB, 28, 4 )
+
+GGL_RESERVE_NEEDS( P_ALPHA_TEST, 0, 3 )
+GGL_RESERVE_NEEDS( P_AA, 3, 1 )
+GGL_RESERVE_NEEDS( P_DEPTH_TEST, 4, 3 )
+GGL_RESERVE_NEEDS( P_MASK_Z, 7, 1 )
+GGL_RESERVE_NEEDS( P_DITHER, 8, 1 )
+GGL_RESERVE_NEEDS( P_FOG, 9, 1 )
+GGL_RESERVE_NEEDS( P_RESERVED1, 10,22 )
+
+GGL_RESERVE_NEEDS( T_FORMAT, 0, 6 )
+GGL_RESERVE_NEEDS( T_RESERVED0, 6, 1 )
+GGL_RESERVE_NEEDS( T_POT, 7, 1 )
+GGL_RESERVE_NEEDS( T_S_WRAP, 8, 2 )
+GGL_RESERVE_NEEDS( T_T_WRAP, 10, 2 )
+GGL_RESERVE_NEEDS( T_ENV, 12, 3 )
+GGL_RESERVE_NEEDS( T_LINEAR, 15, 1 )
+
+const int GGL_NEEDS_WRAP_CLAMP_TO_EDGE = 0;
+const int GGL_NEEDS_WRAP_REPEAT = 1;
+const int GGL_NEEDS_WRAP_11 = 2;
+
+inline uint32_t ggl_wrap_to_needs(uint32_t e) {
+ switch (e) {
+ case GGL_CLAMP: return GGL_NEEDS_WRAP_CLAMP_TO_EDGE;
+ case GGL_REPEAT: return GGL_NEEDS_WRAP_REPEAT;
+ }
+ return 0;
+}
+
+inline uint32_t ggl_blendfactor_to_needs(uint32_t b) {
+ if (b <= 1) return b;
+ return (b & 0xF)+2;
+}
+
+inline uint32_t ggl_needs_to_blendfactor(uint32_t n) {
+ if (n <= 1) return n;
+ return (n - 2) + 0x300;
+}
+
+inline uint32_t ggl_env_to_needs(uint32_t e) {
+ switch (e) {
+ case GGL_REPLACE: return 0;
+ case GGL_MODULATE: return 1;
+ case GGL_DECAL: return 2;
+ case GGL_BLEND: return 3;
+ case GGL_ADD: return 4;
+ }
+ return 0;
+}
+
+inline uint32_t ggl_needs_to_env(uint32_t n) {
+ const uint32_t envs[] = { GGL_REPLACE, GGL_MODULATE,
+ GGL_DECAL, GGL_BLEND, GGL_ADD };
+ return envs[n];
+
+}
+
+// ----------------------------------------------------------------------------
+
+enum {
+ GGL_ENABLE_BLENDING = 0x00000001,
+ GGL_ENABLE_SMOOTH = 0x00000002,
+ GGL_ENABLE_AA = 0x00000004,
+ GGL_ENABLE_LOGIC_OP = 0x00000008,
+ GGL_ENABLE_ALPHA_TEST = 0x00000010,
+ GGL_ENABLE_SCISSOR_TEST = 0x00000020,
+ GGL_ENABLE_TMUS = 0x00000040,
+ GGL_ENABLE_DEPTH_TEST = 0x00000080,
+ GGL_ENABLE_STENCIL_TEST = 0x00000100,
+ GGL_ENABLE_W = 0x00000200,
+ GGL_ENABLE_DITHER = 0x00000400,
+ GGL_ENABLE_FOG = 0x00000800,
+ GGL_ENABLE_POINT_AA_NICE= 0x00001000
+};
+
+// ----------------------------------------------------------------------------
+
+class needs_filter_t;
+struct needs_t {
+ inline int match(const needs_filter_t& filter);
+ inline bool operator == (const needs_t& rhs) const {
+ return (n==rhs.n) &&
+ (p==rhs.p) &&
+ (t[0]==rhs.t[0]) &&
+ (t[1]==rhs.t[1]);
+ }
+ inline bool operator != (const needs_t& rhs) const {
+ return !operator == (rhs);
+ }
+ uint32_t n;
+ uint32_t p;
+ uint32_t t[GGL_TEXTURE_UNIT_COUNT];
+};
+
+inline int compare_type(const needs_t& lhs, const needs_t& rhs) {
+ return memcmp(&lhs, &rhs, sizeof(needs_t));
+}
+
+struct needs_filter_t {
+ needs_t value;
+ needs_t mask;
+};
+
+int needs_t::match(const needs_filter_t& filter) {
+ uint32_t result =
+ ((filter.value.n ^ n) & filter.mask.n) |
+ ((filter.value.p ^ p) & filter.mask.p) |
+ ((filter.value.t[0] ^ t[0]) & filter.mask.t[0]) |
+ ((filter.value.t[1] ^ t[1]) & filter.mask.t[1]);
+ return (result == 0);
+}
+
+// ----------------------------------------------------------------------------
+
+struct context_t;
+class Assembly;
+
+struct blend_state_t {
+ uint32_t src;
+ uint32_t dst;
+ uint32_t src_alpha;
+ uint32_t dst_alpha;
+ uint8_t reserved;
+ uint8_t alpha_separate;
+ uint8_t operation;
+ uint8_t equation;
+};
+
+struct mask_state_t {
+ uint8_t color;
+ uint8_t depth;
+ uint32_t stencil;
+};
+
+struct clear_state_t {
+ GGLclampx r;
+ GGLclampx g;
+ GGLclampx b;
+ GGLclampx a;
+ GGLclampx depth;
+ GGLint stencil;
+ uint32_t colorPacked;
+ uint32_t depthPacked;
+ uint32_t stencilPacked;
+ uint32_t dirty;
+};
+
+struct fog_state_t {
+ uint8_t color[4];
+};
+
+struct logic_op_state_t {
+ uint16_t opcode;
+};
+
+struct alpha_test_state_t {
+ uint16_t func;
+ GGLcolor ref;
+};
+
+struct depth_test_state_t {
+ uint16_t func;
+ GGLclampx clearValue;
+};
+
+struct scissor_t {
+ uint32_t user_left;
+ uint32_t user_right;
+ uint32_t user_top;
+ uint32_t user_bottom;
+ uint32_t left;
+ uint32_t right;
+ uint32_t top;
+ uint32_t bottom;
+};
+
+struct pixel_t {
+ uint32_t c[4];
+ uint8_t s[4];
+};
+
+struct surface_t {
+ union {
+ GGLSurface s;
+ // Keep the following struct field types in line with the corresponding
+ // GGLSurface fields to avoid mismatches leading to errors.
+ struct {
+ GGLsizei reserved;
+ GGLuint width;
+ GGLuint height;
+ GGLint stride;
+ GGLubyte* data;
+ GGLubyte format;
+ GGLubyte dirty;
+ GGLubyte pad[2];
+ };
+ };
+ void (*read) (const surface_t* s, context_t* c,
+ uint32_t x, uint32_t y, pixel_t* pixel);
+ void (*write)(const surface_t* s, context_t* c,
+ uint32_t x, uint32_t y, const pixel_t* pixel);
+};
+
+// ----------------------------------------------------------------------------
+
+struct texture_shade_t {
+ union {
+ struct {
+ int32_t is0;
+ int32_t idsdx;
+ int32_t idsdy;
+ int sscale;
+ int32_t it0;
+ int32_t idtdx;
+ int32_t idtdy;
+ int tscale;
+ };
+ struct {
+ int32_t v;
+ int32_t dx;
+ int32_t dy;
+ int scale;
+ } st[2];
+ };
+};
+
+struct texture_iterators_t {
+ // these are not encoded in the same way than in the
+ // texture_shade_t structure
+ union {
+ struct {
+ GGLfixed ydsdy;
+ GGLfixed dsdx;
+ GGLfixed dsdy;
+ int sscale;
+ GGLfixed ydtdy;
+ GGLfixed dtdx;
+ GGLfixed dtdy;
+ int tscale;
+ };
+ struct {
+ GGLfixed ydvdy;
+ GGLfixed dvdx;
+ GGLfixed dvdy;
+ int scale;
+ } st[2];
+ };
+};
+
+struct texture_t {
+ surface_t surface;
+ texture_iterators_t iterators;
+ texture_shade_t shade;
+ uint32_t s_coord;
+ uint32_t t_coord;
+ uint16_t s_wrap;
+ uint16_t t_wrap;
+ uint16_t min_filter;
+ uint16_t mag_filter;
+ uint16_t env;
+ uint8_t env_color[4];
+ uint8_t enable;
+ uint8_t dirty;
+};
+
+struct raster_t {
+ GGLfixed x;
+ GGLfixed y;
+};
+
+struct framebuffer_t {
+ surface_t color;
+ surface_t read;
+ surface_t depth;
+ surface_t stencil;
+ int16_t *coverage;
+ size_t coverageBufferSize;
+};
+
+// ----------------------------------------------------------------------------
+
+struct iterators_t {
+ int32_t xl;
+ int32_t xr;
+ int32_t y;
+ GGLcolor ydady;
+ GGLcolor ydrdy;
+ GGLcolor ydgdy;
+ GGLcolor ydbdy;
+ GGLfixed ydzdy;
+ GGLfixed ydwdy;
+ GGLfixed ydfdy;
+};
+
+struct shade_t {
+ GGLcolor a0;
+ GGLcolor dadx;
+ GGLcolor dady;
+ GGLcolor r0;
+ GGLcolor drdx;
+ GGLcolor drdy;
+ GGLcolor g0;
+ GGLcolor dgdx;
+ GGLcolor dgdy;
+ GGLcolor b0;
+ GGLcolor dbdx;
+ GGLcolor dbdy;
+ uint32_t z0;
+ GGLfixed32 dzdx;
+ GGLfixed32 dzdy;
+ GGLfixed w0;
+ GGLfixed dwdx;
+ GGLfixed dwdy;
+ uint32_t f0;
+ GGLfixed dfdx;
+ GGLfixed dfdy;
+};
+
+// these are used in the generated code
+// we use this mirror structure to improve
+// data locality in the pixel pipeline
+struct generated_tex_vars_t {
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ uintptr_t data;
+ int32_t dsdx;
+ int32_t dtdx;
+ int32_t spill[2];
+};
+
+struct generated_vars_t {
+ struct {
+ int32_t c;
+ int32_t dx;
+ } argb[4];
+ int32_t aref;
+ int32_t dzdx;
+ int32_t zbase;
+ int32_t f;
+ int32_t dfdx;
+ int32_t spill[3];
+ generated_tex_vars_t texture[GGL_TEXTURE_UNIT_COUNT];
+ int32_t rt;
+ int32_t lb;
+};
+
+// ----------------------------------------------------------------------------
+
+struct state_t {
+ framebuffer_t buffers;
+ texture_t texture[GGL_TEXTURE_UNIT_COUNT];
+ scissor_t scissor;
+ raster_t raster;
+ blend_state_t blend;
+ alpha_test_state_t alpha_test;
+ depth_test_state_t depth_test;
+ mask_state_t mask;
+ clear_state_t clear;
+ fog_state_t fog;
+ logic_op_state_t logic_op;
+ uint32_t enables;
+ uint32_t enabled_tmu;
+ needs_t needs;
+};
+
+// ----------------------------------------------------------------------------
+
+struct context_t {
+ GGLContext procs;
+ state_t state;
+ shade_t shade;
+ iterators_t iterators;
+ generated_vars_t generated_vars __attribute__((aligned(32)));
+ uint8_t ditherMatrix[GGL_DITHER_SIZE] __attribute__((aligned(32)));
+ uint32_t packed;
+ uint32_t packed8888;
+ const GGLFormat* formats;
+ uint32_t dirty;
+ texture_t* activeTMU;
+ uint32_t activeTMUIndex;
+
+ void (*init_y)(context_t* c, int32_t y);
+ void (*step_y)(context_t* c);
+ void (*scanline)(context_t* c);
+ void (*span)(context_t* c);
+ void (*rect)(context_t* c, size_t yc);
+
+ void* base;
+ Assembly* scanline_as;
+ GGLenum error;
+};
+
+// ----------------------------------------------------------------------------
+
+void ggl_init_context(context_t* context);
+void ggl_uninit_context(context_t* context);
+void ggl_error(context_t* c, GGLenum error);
+int64_t ggl_system_time();
+
+// ----------------------------------------------------------------------------
+
+};
+
+#endif // ANDROID_GGL_CONTEXT_H
+