1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/buffer.cpp
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright 2006, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** See the License for the specific language governing permissions and
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <assert.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "buffer.h"
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void read_pixel(const surface_t* s, context_t* c,
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel);
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void write_pixel(const surface_t* s, context_t* c,
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, const pixel_t* pixel);
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void readRGB565(const surface_t* s, context_t* c,
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel);
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void readABGR8888(const surface_t* s, context_t* c,
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel);
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t logic_op(int op, uint32_t s, uint32_t d);
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t extract(uint32_t v, int h, int l, int bits);
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t expand(uint32_t v, int sbits, int dbits);
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t downshift_component(uint32_t in, uint32_t v,
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int sh, int sl, int dh, int dl, int ch, int cl, int dither);
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_init_texture(context_t* c)
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) {
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texture_t& t = c->state.texture[i];
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.s_coord = GGL_ONE_TO_ONE;
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.t_coord = GGL_ONE_TO_ONE;
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.s_wrap = GGL_REPEAT;
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.t_wrap = GGL_REPEAT;
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.min_filter = GGL_NEAREST;
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.mag_filter = GGL_NEAREST;
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        t.env = GGL_MODULATE;
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->activeTMU = &(c->state.texture[0]);
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_set_surface(context_t* c, surface_t* dst, const GGLSurface* src)
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->width = src->width;
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->height = src->height;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->stride = src->stride;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->data = src->data;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->format = src->format;
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst->dirty = 1;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (__builtin_expect(dst->stride < 0, false)) {
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLFormat& pixelFormat(c->formats[dst->format]);
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int32_t bpr = -dst->stride * pixelFormat.size;
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dst->data += bpr * (dst->height-1);
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void pick_read_write(surface_t* s)
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // Choose best reader/writers.
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (s->format) {
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_PIXEL_FORMAT_RGBA_8888:    s->read = readABGR8888;  break;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case GGL_PIXEL_FORMAT_RGB_565:      s->read = readRGB565;    break;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:                            s->read = read_pixel;    break;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s->write = write_pixel;
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_pick_texture(context_t* c)
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) {
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        surface_t& s = c->state.texture[i].surface;
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((!c->state.texture[i].enable) || (!s.dirty))
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s.dirty = 0;
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pick_read_write(&s);
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        generated_tex_vars_t& gen = c->generated_vars.texture[i];
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gen.width   = s.width;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gen.height  = s.height;
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gen.stride  = s.stride;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        gen.data    = int32_t(s.data);
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_pick_cb(context_t* c)
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    surface_t& s = c->state.buffers.color;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (s.dirty) {
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        s.dirty = 0;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pick_read_write(&s);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid read_pixel(const surface_t* s, context_t* c,
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel)
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert((x < s->width) && (y < s->height));
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLFormat* f = &(c->formats[s->format]);
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int32_t index = x + (s->stride * y);
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t* const data = s->data + index * f->size;
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t v = 0;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (f->size) {
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 1:		v = *data;									break;
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 2:		v = *(uint16_t*)data;						break;
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 3:		v = (data[2]<<16)|(data[1]<<8)|data[0];     break;
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 4:		v = GGL_RGBA_TO_HOST(*(uint32_t*)data);		break;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pixel->s[i] = f->c[i].h - f->c[i].l;
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (pixel->s[i])
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pixel->c[i] = extract(v,  f->c[i].h,  f->c[i].l, f->size*8);
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid readRGB565(const surface_t* s, context_t* c,
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel)
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint16_t v = *(reinterpret_cast<uint16_t*>(s->data) + (x + (s->stride * y)));
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[0] = 0;
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[1] = v>>11;
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[2] = (v>>5)&0x3F;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[3] = v&0x1F;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[0] = 0;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[1] = 5;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[2] = 6;
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[3] = 5;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid readABGR8888(const surface_t* s, context_t* c,
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, pixel_t* pixel)
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t v = *(reinterpret_cast<uint32_t*>(s->data) + (x + (s->stride * y)));
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    v = GGL_RGBA_TO_HOST(v);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[0] = v>>24;        // A
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[1] = v&0xFF;       // R
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[2] = (v>>8)&0xFF;  // G
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->c[3] = (v>>16)&0xFF; // B
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[0] =
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[1] =
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[2] =
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pixel->s[3] = 8;
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid write_pixel(const surface_t* s, context_t* c,
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t x, uint32_t y, const pixel_t* pixel)
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert((x < s->width) && (y < s->height));
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int dither = -1;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c->state.enables & GGL_ENABLE_DITHER) {
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dither = c->ditherMatrix[ (x & GGL_DITHER_MASK) +
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ((y & GGL_DITHER_MASK)<<GGL_DITHER_ORDER_SHIFT) ];
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLFormat* f = &(c->formats[s->format]);
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int32_t index = x + (s->stride * y);
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t* const data = s->data + index * f->size;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t mask = 0;
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t v = 0;
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i=0 ; i<4 ; i++) {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int component_mask = 1 << i;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (f->components>=GGL_LUMINANCE &&
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (i==GGLFormat::GREEN || i==GGLFormat::BLUE)) {
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // destinations L formats don't have G or B
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            continue;
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int l = f->c[i].l;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const int h = f->c[i].h;
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (h && (c->state.mask.color & component_mask)) {
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mask |= (((1<<(h-l))-1)<<l);
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            uint32_t u = pixel->c[i];
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int32_t pixelSize = pixel->s[i];
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (pixelSize < (h-l)) {
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                u = expand(u, pixelSize, h-l);
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                pixelSize = h-l;
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            v = downshift_component(v, u, pixelSize, 0, h, l, 0, 0, dither);
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((c->state.mask.color != 0xF) ||
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        (c->state.enables & GGL_ENABLE_LOGIC_OP)) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        uint32_t d = 0;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (f->size) {
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 1:	d = *data;									break;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 2:	d = *(uint16_t*)data;						break;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 3:	d = (data[2]<<16)|(data[1]<<8)|data[0];     break;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case 4:	d = GGL_RGBA_TO_HOST(*(uint32_t*)data);		break;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c->state.enables & GGL_ENABLE_LOGIC_OP) {
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            v = logic_op(c->state.logic_op.opcode, v, d);
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            v &= mask;
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        v |= (d & ~mask);
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (f->size) {
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 1:		*data = v;									break;
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 2:		*(uint16_t*)data = v;						break;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 3:
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            data[0] = v;
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            data[1] = v>>8;
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            data[2] = v>>16;
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case 4:		*(uint32_t*)data = GGL_HOST_TO_RGBA(v);     break;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic uint32_t logic_op(int op, uint32_t s, uint32_t d)
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(op) {
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_CLEAR:         return 0;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND:           return s & d;
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND_REVERSE:   return s & ~d;
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_COPY:          return s;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_AND_INVERTED:  return ~s & d;
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NOOP:          return d;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_XOR:           return s ^ d;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR:            return s | d;
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NOR:           return ~(s | d);
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_EQUIV:         return ~(s ^ d);
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_INVERT:        return ~d;
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR_REVERSE:    return s | ~d;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_COPY_INVERTED: return ~s;
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_OR_INVERTED:   return ~s | d;
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_NAND:          return ~(s & d);
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case GGL_SET:           return ~0;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    };
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return s;
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ggl_expand(uint32_t v, int sbits, int dbits)
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return expand(v, sbits, dbits);
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t ggl_pack_color(context_t* c, int32_t format,
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLcolor r, GGLcolor g, GGLcolor b, GGLcolor a)
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLFormat* f = &(c->formats[format]);
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t p = 0;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int32_t hbits = GGL_COLOR_BITS;
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const int32_t lbits = GGL_COLOR_BITS - 8;
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = downshift_component(p, r,   hbits, lbits,  f->rh, f->rl, 0, 1, -1);
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = downshift_component(p, g,   hbits, lbits,  f->gh, f->gl, 0, 1, -1);
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = downshift_component(p, b,   hbits, lbits,  f->bh, f->bl, 0, 1, -1);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    p = downshift_component(p, a,   hbits, lbits,  f->ah, f->al, 0, 1, -1);
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (f->size) {
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 1: p |= p << 8;    // fallthrough
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 2: p |= p << 16;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return p;
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// extract a component from a word
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t extract(uint32_t v, int h, int l, int bits)
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	assert(h);
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (l) {
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		v >>= l;
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (h != bits) {
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		v &= (1<<(h-l))-1;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return v;
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// expand a component from sbits to dbits
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t expand(uint32_t v, int sbits, int dbits)
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (dbits > sbits) {
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        assert(sbits);
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (sbits==1) {
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            v = (v<<dbits) - v;
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (dbits % sbits) {
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                v <<= (dbits-sbits);
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                dbits -= sbits;
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                do {
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    v |= v>>sbits;
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    dbits -= sbits;
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    sbits *= 2;
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } while (dbits>0);
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                dbits -= sbits;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                do {
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    v |= v<<sbits;
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    dbits -= sbits;
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if (sbits*2 < dbits) {
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        sbits *= 2;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                } while (dbits > 0);
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return v;
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// downsample a component from sbits to dbits
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// and shift / construct the pixel
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint32_t downshift_component(	uint32_t in, uint32_t v,
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                int sh, int sl,		// src
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                int dh, int dl,		// dst
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                int ch, int cl,		// clear
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                int dither)
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const int sbits = sh-sl;
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const int dbits = dh-dl;
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	assert(sbits>=dbits);
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (sbits>dbits) {
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (dither>=0) {
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            v -= (v>>dbits);				// fix up
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            const int shift = (GGL_DITHER_BITS - (sbits-dbits));
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (shift >= 0)   v += (dither >> shift) << sl;
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            else              v += (dither << (-shift)) << sl;
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // don't do that right now, so we can reproduce the same
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // artifacts we get on ARM (Where we don't do this)
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // -> this is not really needed if we don't dither
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //if (dBits > 1) { // result already OK if dBits==1
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //    v -= (v>>dbits);				// fix up
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //    v += 1 << ((sbits-dbits)-1);	// rounding
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            //}
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	// we need to clear the high bits of the source
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ch) {
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		v <<= 32-sh;
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		sl += 32-sh;
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        sh = 32;
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (dl) {
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (cl || (sbits>dbits)) {
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			v >>= sh-dbits;
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sl = 0;
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			sh = dbits;
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            in |= v<<dl;
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			// sbits==dbits and we don't need to clean the lower bits
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			// so we just have to shift the component to the right location
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int shift = dh-sh;
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            in |= v<<shift;
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		// destination starts at bit 0
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		// ie: sh-dh == sh-dbits
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		int shift = sh-dh;
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (shift > 0)      in |= v>>shift;
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else if (shift < 0) in |= v<<shift;
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else                in |= v;
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return in;
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
385