1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* libs/opengles/mipmap.cpp
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2006, The Android Open Source Project
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** you may not use this file except in compliance with the License.
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** You may obtain a copy of the License at
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** See the License for the specific language governing permissions and
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License.
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "context.h"
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "state.h"
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "texture.h"
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "TextureObjectManager.h"
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ----------------------------------------------------------------------------
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t buildAPyramid(ogles_context_t* c, EGLTextureObject* tex)
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int level = 0;
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLSurface* base = &tex->surface;
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const GGLFormat& pixelFormat(c->rasterizer.formats[base->format]);
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int w = base->width;
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int h = base->height;
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((w&h) == 1)
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return NO_ERROR;
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    w = (w>>1) ? : 1;
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    h = (h>>1) ? : 1;
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    while(true) {
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        ++level;
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        const int bpr = w * pixelFormat.size;
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (tex->reallocate(level, w, h, w,
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                base->format, base->compressedFormat, bpr) != NO_ERROR) {
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return NO_MEMORY;
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int stride = w;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int bs = base->stride;
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        GGLSurface& cur = tex->editMip(level);
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (base->format == GGL_PIXEL_FORMAT_RGB_565)
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t const * src = (uint16_t const *)base->data;
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t* dst = (uint16_t*)cur.data;
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const uint32_t mask = 0x07E0F81F;
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y=0 ; y<h ; y++) {
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                size_t offset = (y*2) * bs;
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<w ; x++) {
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p00 = src[offset];
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p10 = src[offset+1];
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p01 = src[offset+bs];
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p11 = src[offset+bs+1];
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p00 = (p00 | (p00 << 16)) & mask;
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p01 = (p01 | (p01 << 16)) & mask;
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p10 = (p10 | (p10 << 16)) & mask;
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p11 = (p11 | (p11 << 16)) & mask;
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t grb = ((p00 + p10 + p01 + p11) >> 2) & mask;
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rgb = (grb & 0xFFFF) | (grb >> 16);
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    dst[x + y*stride] = rgb;
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    offset += 2;
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (base->format == GGL_PIXEL_FORMAT_RGBA_5551)
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t const * src = (uint16_t const *)base->data;
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t* dst = (uint16_t*)cur.data;
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y=0 ; y<h ; y++) {
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                size_t offset = (y*2) * bs;
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<w ; x++) {
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p00 = src[offset];
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p10 = src[offset+1];
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p01 = src[offset+bs];
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p11 = src[offset+bs+1];
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t r = ((p00>>11)+(p10>>11)+(p01>>11)+(p11>>11)+2)>>2;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t g = (((p00>>6)+(p10>>6)+(p01>>6)+(p11>>6)+2)>>2)&0x3F;
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t b = ((p00&0x3E)+(p10&0x3E)+(p01&0x3E)+(p11&0x3E)+4)>>3;
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t a = ((p00&1)+(p10&1)+(p01&1)+(p11&1)+2)>>2;
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    dst[x + y*stride] = (r<<11)|(g<<6)|(b<<1)|a;
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    offset += 2;
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (base->format == GGL_PIXEL_FORMAT_RGBA_8888)
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t const * src = (uint32_t const *)base->data;
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t* dst = (uint32_t*)cur.data;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y=0 ; y<h ; y++) {
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                size_t offset = (y*2) * bs;
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<w ; x++) {
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p00 = src[offset];
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p10 = src[offset+1];
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p01 = src[offset+bs];
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p11 = src[offset+bs+1];
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rb00 = p00 & 0x00FF00FF;
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rb01 = p01 & 0x00FF00FF;
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rb10 = p10 & 0x00FF00FF;
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rb11 = p11 & 0x00FF00FF;
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t ga00 = (p00 >> 8) & 0x00FF00FF;
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t ga01 = (p01 >> 8) & 0x00FF00FF;
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t ga10 = (p10 >> 8) & 0x00FF00FF;
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t ga11 = (p11 >> 8) & 0x00FF00FF;
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rb = (rb00 + rb01 + rb10 + rb11)>>2;
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t ga = (ga00 + ga01 + ga10 + ga11)>>2;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rgba = (rb & 0x00FF00FF) | ((ga & 0x00FF00FF)<<8);
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    dst[x + y*stride] = rgba;
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    offset += 2;
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if ((base->format == GGL_PIXEL_FORMAT_RGB_888) ||
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 (base->format == GGL_PIXEL_FORMAT_LA_88) ||
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 (base->format == GGL_PIXEL_FORMAT_A_8) ||
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                 (base->format == GGL_PIXEL_FORMAT_L_8))
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            int skip;
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            switch (base->format) {
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case GGL_PIXEL_FORMAT_RGB_888:  skip = 3;   break;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            case GGL_PIXEL_FORMAT_LA_88:    skip = 2;   break;
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            default:                        skip = 1;   break;
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t const * src = (uint8_t const *)base->data;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint8_t* dst = (uint8_t*)cur.data;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            bs *= skip;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            stride *= skip;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y=0 ; y<h ; y++) {
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                size_t offset = (y*2) * bs;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<w ; x++) {
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    for (int c=0 ; c<skip ; c++) {
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        uint32_t p00 = src[c+offset];
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        uint32_t p10 = src[c+offset+skip];
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        uint32_t p01 = src[c+offset+bs];
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        uint32_t p11 = src[c+offset+bs+skip];
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        dst[x + y*stride + c] = (p00 + p10 + p01 + p11) >> 2;
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    offset += 2*skip;
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (base->format == GGL_PIXEL_FORMAT_RGBA_4444)
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        {
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t const * src = (uint16_t const *)base->data;
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t* dst = (uint16_t*)cur.data;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y=0 ; y<h ; y++) {
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                size_t offset = (y*2) * bs;
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x=0 ; x<w ; x++) {
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p00 = src[offset];
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p10 = src[offset+1];
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p01 = src[offset+bs];
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t p11 = src[offset+bs+1];
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p00 = ((p00 << 12) & 0x0F0F0000) | (p00 & 0x0F0F);
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p10 = ((p10 << 12) & 0x0F0F0000) | (p10 & 0x0F0F);
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p01 = ((p01 << 12) & 0x0F0F0000) | (p01 & 0x0F0F);
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    p11 = ((p11 << 12) & 0x0F0F0000) | (p11 & 0x0F0F);
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rbga = (p00 + p10 + p01 + p11) >> 2;
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    uint32_t rgba = (rbga & 0x0F0F) | ((rbga>>12) & 0xF0F0);
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    dst[x + y*stride] = rgba;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    offset += 2;
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
177e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block            ALOGE("Unsupported format (%d)", base->format);
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            return BAD_TYPE;
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // exit condition: we just processed the 1x1 LODs
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if ((w&h) == 1)
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            break;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        base = &cur;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        w = (w>>1) ? : 1;
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        h = (h>>1) ? : 1;
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return NO_ERROR;
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
193