1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* libs/pixelflinger/raster.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
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "raster.h"
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "trap.h"
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y);
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_rasterPos2i(void* con, GGLint x, GGLint y);
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void ggl_copyPixels(void* con, GGLint xs, GGLint ys,
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLsizei width, GGLsizei height, GGLenum type);
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_init_raster(context_t* c)
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLContext& procs = *(GGLContext*)c;
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, copyPixels);
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, rasterPos2x);
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_INIT_PROC(procs, rasterPos2i);
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y)
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // raster pos should be processed just like glVertex
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.raster.x = x;
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->state.raster.y = y;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_rasterPos2i(void* con, GGLint x, GGLint y)
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ggl_rasterPos2x(con, gglIntToFixed(x), gglIntToFixed(y));
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid ggl_copyPixels(void* con, GGLint xs, GGLint ys,
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLsizei width, GGLsizei height, GGLenum type)
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, con);
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // color-buffer
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    surface_t* cb = &(c->state.buffers.color);
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // undefined behaviour if we try to copy from outside the surface
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (uint32_t(xs) > cb->width)
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (uint32_t(ys) > cb->height)
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (uint32_t(xs + width) > cb->width)
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (uint32_t(ys + height) > cb->height)
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // copy to current raster position
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLint xd = gglFixedToIntRound(c->state.raster.x);
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGLint yd = gglFixedToIntRound(c->state.raster.y);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // clip to scissor
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (xd < GGLint(c->state.scissor.left)) {
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLint offset = GGLint(c->state.scissor.left) - xd;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        xd = GGLint(c->state.scissor.left);
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        xs += offset;
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        width -= offset;
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (yd < GGLint(c->state.scissor.top)) {
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        GGLint offset = GGLint(c->state.scissor.top) - yd;
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        yd = GGLint(c->state.scissor.top);
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ys += offset;
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        height -= offset;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((xd + width) > GGLint(c->state.scissor.right)) {
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        width = GGLint(c->state.scissor.right) - xd;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((yd + height) > GGLint(c->state.scissor.bottom)) {
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        height = GGLint(c->state.scissor.bottom) - yd;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (width<=0 || height<=0) {
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return; // nothing to copy
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (xs==xd && ys==yd) {
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // nothing to do, but be careful, this might not be true when we support
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // gglPixelTransfer, gglPixelMap and gglPixelZoom
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLFormat* fp = &(c->formats[cb->format]);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t* src = reinterpret_cast<uint8_t*>(cb->data)
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            + (xs + (cb->stride * ys)) * fp->size;
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data)
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            + (xd + (cb->stride * yd)) * fp->size;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const size_t bpr = cb->stride * fp->size;
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const size_t rowsize = width * fp->size;
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    size_t yc = height;
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (ys < yd) {
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // bottom to top
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        src += height * bpr;
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dst += height * bpr;
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dst -= bpr;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            src -= bpr;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            memcpy(dst, src, rowsize);
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } while (--yc);
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ys == yd) {
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // might be right to left
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            do {
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                memmove(dst, src, rowsize);
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                dst += bpr;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                src += bpr;
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } while (--yc);
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            // top to bottom
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            do {
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                memcpy(dst, src, rowsize);
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                dst += bpr;
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                src += bpr;
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } while (--yc);
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; // namespace android
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectusing namespace android;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1466e1a9430e8e8de13109f1b234d937541a45a8ac5Jim HuangGGLint gglBitBlit(GGLContext* con, int tmu, GGLint crop[4], GGLint where[4])
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    GGL_CONTEXT(c, (void*)con);
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     GGLint x = where[0];
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     GGLint y = where[1];
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     GGLint w = where[2];
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     GGLint h = where[3];
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    // exclsively enable this tmu
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLSurface& cbSurface = c->state.buffers.color.s;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->procs.activeTexture(c, tmu);
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    c->procs.disable(c, GGL_W_LERP);
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    uint32_t tmus = 1UL<<tmu;
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (c->state.enabled_tmu != tmus) {
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->activeTMU->enable = 1;
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->state.enabled_tmu = tmus;
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->state.enables |= GGL_ENABLE_TMUS;
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ggl_state_changed(c, GGL_TMU_STATE);
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLint Wcr = crop[2];
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const GGLint Hcr = crop[3];
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ((w == Wcr) && (h == Hcr)) {
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Ucr = crop[0];
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Vcr = crop[1];
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint s0  = Ucr - x;
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint t0  = Vcr - y;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texCoord2i(c, s0, t0);
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.recti(c, x, y, x+w, y+h);
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int32_t texcoords[8];
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        x = gglIntToFixed(x);
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        y = gglIntToFixed(y);
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // we CLAMP here, which works with premultiplied (s,t)
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP);
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP);
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC);
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Ucr = crop[0] << 16;
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Vcr = crop[1] << 16;
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Wcr = crop[2] << 16;
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const GGLint Hcr = crop[3] << 16;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // computes texture coordinates (pre-multiplied)
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int32_t dsdx = Wcr / w;   // dsdx = ((Wcr/w)/Wt)*Wt
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int32_t dtdy = Hcr / h;   // dtdy = ((Hcr/h)/Ht)*Ht
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int32_t s0   = Ucr - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int32_t t0   = Vcr - gglMulx(dtdy, y); // t0 = Vcr - y * dtdy
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[0] = s0;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[1] = dsdx;
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[2] = 0;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[3] = t0;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[4] = 0;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[5] = dtdy;
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[6] = 0;
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        texcoords[7] = 0;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.texCoordGradScale8xv(c, tmu, texcoords);
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        c->procs.recti(c,
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                gglFixedToIntRound(x),
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                gglFixedToIntRound(y),
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                gglFixedToIntRound(x)+w,
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                gglFixedToIntRound(y)+h);
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
218