copybit.cpp revision 42bf621e801183028066e6947fdd22eae8693a02
11473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian/* 21473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** 31473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** Copyright 2009, The Android Open Source Project 41473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** 51473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** Licensed under the Apache License, Version 2.0 (the "License"); 61473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** you may not use this file except in compliance with the License. 71473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** You may obtain a copy of the License at 81473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** 91473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** http://www.apache.org/licenses/LICENSE-2.0 101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** 111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** Unless required by applicable law or agreed to in writing, software 121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** distributed under the License is distributed on an "AS IS" BASIS, 131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 141473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** See the License for the specific language governing permissions and 151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian** limitations under the License. 161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian*/ 171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <stdlib.h> 191473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <stdio.h> 201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 211473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "context.h" 221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "fp.h" 231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "state.h" 241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "matrix.h" 251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "vertex.h" 261473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "light.h" 271473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "primitives.h" 281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "texture.h" 291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "BufferObjectManager.h" 301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "TextureObjectManager.h" 31350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian 321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <hardware/gralloc.h> 331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include <hardware/copybit.h> 34350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian#include <private/ui/android_natives_priv.h> 351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian#include "gralloc_priv.h" 361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 3703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 3803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian#define DEBUG_COPYBIT true 3903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian// ---------------------------------------------------------------------------- 411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopiannamespace android { 431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 44350d651706d8f484d9aeb539d491526f822fa84aMathias Agopianstatic void textureToCopyBitImage( 45350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian const GGLSurface* surface, buffer_handle_t buffer, copybit_image_t* img) 46350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian{ 47350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian // we know private_handle_t is good here 48350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian private_handle_t* hnd = (private_handle_t*)buffer; 491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian img->w = surface->stride; 501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian img->h = surface->height; 511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian img->format = surface->format; 52350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian img->offset = hnd->offset; 531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian img->base = surface->data; 54350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian img->fd = hnd->fd; 551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstruct clipRectRegion : public copybit_region_t { 584d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian clipRectRegion(ogles_context_t* c) 594d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian { 604d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian scissor_t const* scissor = &c->rasterizer.state.scissor; 614d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian r.l = scissor->left; 624d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian r.t = scissor->top; 634d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian r.r = scissor->right; 644d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian r.b = scissor->bottom; 654d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian next = iterate; 661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianprivate: 681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { 694d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian *rect = static_cast<clipRectRegion const*>(self)->r; 704d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian const_cast<copybit_region_t *>(self)->next = iterate_done; 714d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian return 1; 724d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian } 734d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian static int iterate_done(copybit_region_t const *, copybit_rect_t*) { 741473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return 0; 751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 764d63fb113b542f0474c16d8f2c8a1240b44f0ca2Mathias Agopian copybit_rect_t r; 771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian}; 781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstatic bool supportedCopybitsFormat(int format) { 801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian switch (format) { 811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_8888: 821473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGB_565: 831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_BGRA_8888: 841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_5551: 851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_4444: 861473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_YCbCr_422_SP: 871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_YCbCr_420_SP: 881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return true; 891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian default: 901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 911473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 941473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstatic bool hasAlpha(int format) { 951473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian switch (format) { 961473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_8888: 971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_BGRA_8888: 981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_5551: 991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case COPYBIT_FORMAT_RGBA_4444: 1001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return true; 1011473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian default: 1021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 1051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstatic inline int fixedToByte(GGLfixed val) { 1071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return (val - (val >> 8)) >> 8; 1081473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 1091473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian/** 1111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * Performs a quick check of the rendering state. If this function returns 1121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * false we cannot use the copybit driver. 1131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 1141473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstatic bool checkContext(ogles_context_t* c) { 1161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 117350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian // By convention copybitQuickCheckContext() has already returned true. 1181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // avoid checking the same information again. 1191473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 12003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (c->copybits.blitEngine == NULL) { 12103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "no copybit hal"); 12203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian return false; 12303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian } 12403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 12503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (c->rasterizer.state.enables 12603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) { 12703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog"); 1281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 131350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian // Note: The drawSurfaceBuffer is only set for destination 1321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // surfaces types that are supported by the hardware and 1331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // do not have an alpha channel. So we don't have to re-check that here. 1341473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian static const int tmu = 0; 1361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian texture_unit_t& u(c->textures.tmu[tmu]); 1371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLTextureObject* textureObject = u.texture; 1381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (!supportedCopybitsFormat(textureObject->surface.format)) { 14003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "texture format not supported"); 1411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1431473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return true; 1441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 1451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianstatic bool copybit(GLint x, GLint y, 1481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint w, GLint h, 1491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLTextureObject* textureObject, 1501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GLint* crop_rect, 1511473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int transform, 1521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian ogles_context_t* c) 1531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 1541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // We assume checkContext has already been called and has already 1551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // returned true. 1561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; 1581473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian y = cbSurface.height - (y + h); 1601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GLint Ucr = crop_rect[0]; 1621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GLint Vcr = crop_rect[1]; 1631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GLint Wcr = crop_rect[2]; 1641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GLint Hcr = crop_rect[3]; 1651473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int32_t dsdx = (Wcr << 16) / w; // dsdx = ((Wcr/w)/Wt)*Wt 1671473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int32_t dtdy = ((-Hcr) << 16) / h; // dtdy = -((Hcr/h)/Ht)*Ht 1681473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 1691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (dsdx < c->copybits.minScale || dsdx > c->copybits.maxScale 1701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian || dtdy < c->copybits.minScale || dtdy > c->copybits.maxScale) { 1711473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // The requested scale is out of the range the hardware 1721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // can support. 17303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, 17403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian "scale out of range dsdx=%08x, dtdy=%08x", dsdx, dtdy); 1751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 17842bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // copybit doesn't say anything about filtering, so we can't 17942bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // discriminate. On msm7k, copybit will always filter. 18042bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // the code below handles min/mag filters, we keep it as a reference. 18142bf621e801183028066e6947fdd22eae8693a02Mathias Agopian 18242bf621e801183028066e6947fdd22eae8693a02Mathias Agopian#ifdef MIN_MAG_FILTER 1831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int32_t texelArea = gglMulx(dtdy, dsdx); 1841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) { 1851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Non-linear filtering on a texture enlargement. 18603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR"); 1871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 1891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) { 1901473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Non-linear filtering on an texture shrink. 19103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR"); 1921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 1931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 19442bf621e801183028066e6947fdd22eae8693a02Mathias Agopian#endif 19542bf621e801183028066e6947fdd22eae8693a02Mathias Agopian 1961473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const uint32_t enables = c->rasterizer.state.enables; 1971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian int planeAlpha = 255; 1981473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian static const int tmu = 0; 1991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian texture_t& tev(c->rasterizer.state.texture[tmu]); 2001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian bool srcTextureHasAlpha = hasAlpha(textureObject->surface.format); 2011473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian switch (tev.env) { 2021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case GGL_REPLACE: 2041473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (!srcTextureHasAlpha) { 2051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian planeAlpha = fixedToByte(c->currentColorClamped.a); 2061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian break; 2081473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2091473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian case GGL_MODULATE: 2101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (! (c->currentColorClamped.r == FIXED_ONE 2111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && c->currentColorClamped.g == FIXED_ONE 2121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && c->currentColorClamped.b == FIXED_ONE)) { 21303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "MODULATE and non white color"); 2141473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian planeAlpha = fixedToByte(c->currentColorClamped.a); 2171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian break; 2181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2191473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian default: 2201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Incompatible texture environment. 22103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); 2221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2231473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian bool blending = false; 2261473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2271473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if ((enables & GGL_ENABLE_BLENDING) 2281473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && !(c->rasterizer.state.blend.src == GL_ONE 2291473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && c->rasterizer.state.blend.dst == GL_ZERO)) { 2301473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Blending is OK if it is 2311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // the exact kind of blending that the copybits hardware supports. 2321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Note: The hardware only supports 2331473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA, 2341473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA. 2351473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case, 2361473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // because the performance is worth it, even if the results are 2371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // not correct. 2381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA 2391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian || c->rasterizer.state.blend.src == GL_ONE) 2401473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA 2411473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian && c->rasterizer.state.blend.alpha_separate == 0)) { 2421473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Incompatible blend mode. 24303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode"); 2441473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2451473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2461473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian blending = true; 2471473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } else { 2481473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // No blending is OK if we are not using alpha. 2491473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (srcTextureHasAlpha || planeAlpha != 255) { 2501473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Incompatible alpha 25103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "incompatible alpha"); 2521473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2531473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2541473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2551473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2561473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if (srcTextureHasAlpha && planeAlpha != 255) { 2571473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // Can't do two types of alpha at once. 25803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "src alpha and plane alpha"); 2591473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2601473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2611473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2621473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // LOGW("calling copybits"); 2631473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit_device_t* copybit = c->copybits.blitEngine; 265350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian 2661473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit_image_t dst; 267350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian buffer_handle_t target_hnd = c->copybits.drawSurfaceBuffer; 268350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian textureToCopyBitImage(&cbSurface, target_hnd, &dst); 2691473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit_rect_t drect = {x, y, x+w, y+h}; 2701473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 271350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian // we know private_handle_t is good here 2721473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit_image_t src; 273350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian buffer_handle_t source_hnd = textureObject->buffer->handle; 274350d651706d8f484d9aeb539d491526f822fa84aMathias Agopian textureToCopyBitImage(&textureObject->surface, source_hnd, &src); 2751473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; 2761473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2771473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); 2781473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); 2791473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit->set_parameter(copybit, COPYBIT_DITHER, 2801473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian (enables & GGL_ENABLE_DITHER) ? COPYBIT_ENABLE : COPYBIT_DISABLE); 2811473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2821473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian clipRectRegion it(c); 2831473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); 2841473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return true; 2851473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 2861473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian/* 2881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * Try to draw a triangle fan with copybit, return false if we fail. 2891473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 29003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopianbool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) 29103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian{ 29203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (!checkContext(c)) { 2931473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 2941473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 2951473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 2961473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian c->arrays.compileElements(c, c->vc.vBuffer, 0, 4); 2971473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 29803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // we detect if we're dealing with a rectangle, by comparing the 29903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // rectangles {v0,v2} and {v1,v3} which should be identical. 30003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 30142bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // NOTE: we should check that the rectangle is window aligned, however 30242bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // if we do that, the optimization won't be taken in a lot of cases. 30342bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // Since this code is intended to be used with SurfaceFlinger only, 30442bf621e801183028066e6947fdd22eae8693a02Mathias Agopian // so it's okay... 30542bf621e801183028066e6947fdd22eae8693a02Mathias Agopian 30603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& v0 = c->vc.vBuffer[0].window; 30703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& v1 = c->vc.vBuffer[1].window; 30803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& v2 = c->vc.vBuffer[2].window; 30903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& v3 = c->vc.vBuffer[3].window; 31003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int l = min(v0.x, v2.x); 31103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int b = min(v0.y, v2.y); 31203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int r = max(v0.x, v2.x); 31303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int t = max(v0.y, v2.y); 31403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) || 31503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) { 31603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle"); 31703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian return false; 3181473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 31903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 32003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& t0 = c->vc.vBuffer[0].texture[0]; 32103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& t1 = c->vc.vBuffer[1].texture[0]; 32203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& t2 = c->vc.vBuffer[2].texture[0]; 32303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const vec4_t& t3 = c->vc.vBuffer[3].texture[0]; 32403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int txl = min(t0.x, t2.x); 32503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int txb = min(t0.y, t2.y); 32603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int txr = max(t0.x, t2.x); 32703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int txt = max(t0.y, t2.y); 32803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) || 32903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) { 33003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle"); 3311473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 3321473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 33303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if ((txl != 0) || (txb != 0) || 33403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian (txr != FIXED_ONE) || (txt != FIXED_ONE)) { 33503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // we could probably handle this case, if we wanted to 33603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian LOGD_IF(DEBUG_COPYBIT, "texture is cropped"); 3371473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 3381473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 3391473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 34003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // at this point, we know we are dealing with a rectangle, so we 34103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // only need to consider 3 vertices for computing the jacobians 34203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 34303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dx01 = v1.x - v0.x; 34403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dy01 = v1.y - v0.y; 34503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dx02 = v2.x - v0.x; 34603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dy02 = v2.y - v0.y; 34703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int ds01 = t1.S - t0.S; 34803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dt01 = t1.T - t0.T; 34903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int ds02 = t2.S - t0.S; 35003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int dt02 = t2.T - t0.T; 35103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian const int area = dx01*dy02 - dy01*dx02; 35203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int dsdx, dsdy, dtdx, dtdy; 35303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (area >= 0) { 35403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dsdx = ds01*dy02 - ds02*dy01; 35503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dsdy = ds02*dx01 - ds01*dx02; 35603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dtdx = dt01*dy02 - dt02*dy01; 35703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dtdy = dt02*dx01 - dt01*dx02; 35803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian } else { 35903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dsdx = ds02*dy01 - ds01*dy02; 36003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dsdy = ds01*dx02 - ds02*dx01; 36103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dtdx = dt02*dy01 - dt01*dy02; 36203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian dtdy = dt01*dx02 - dt02*dx01; 36303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian } 3641473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 36503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // here we rely on the fact that we know the transform is 36603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // a rigid-body transform AND that it can only rotate in 90 degrees 36703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // increments 36803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian 36903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int transform = 0; 37003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (dsdx == 0) { 37103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // 90 deg rotation case 37203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // [ 0 dtdx ] 37303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // [ dsdx 0 ] 37403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian transform |= COPYBIT_TRANSFORM_ROT_90; 37503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted 37603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (dtdx > 0) 37703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian transform |= COPYBIT_TRANSFORM_FLIP_H; 37803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (dsdy < 0) 37903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian transform |= COPYBIT_TRANSFORM_FLIP_V; 38003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian } else { 38103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // [ dsdx 0 ] 38203a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // [ 0 dtdy ] 38303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (dsdx < 0) 38403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian transform |= COPYBIT_TRANSFORM_FLIP_H; 38503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (dtdy < 0) 38603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian transform |= COPYBIT_TRANSFORM_FLIP_V; 3871473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 3881473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 38903a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform); 39003a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian //LOGD("A=%f\tB=%f\nC=%f\tD=%f", 39103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian // dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0); 3921473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 39303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int x = l >> 4; 39403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int y = b >> 4; 39503a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int w = (r-l) >> 4; 39603a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian int h = (t-b) >> 4; 39703a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian texture_unit_t& u(c->textures.tmu[0]); 39803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian EGLTextureObject* textureObject = u.texture; 3991473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint tWidth = textureObject->surface.width; 4001473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint tHeight = textureObject->surface.height; 4011473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight}; 4021473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; 4031473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian y = cbSurface.height - (y + h); 40403a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian return copybit(x, y, w, h, textureObject, crop_rect, transform, c); 4051473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 4061473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4071473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian/* 4081473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian * Try to drawTexiOESWithCopybit, return false if we fail. 4091473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian */ 4101473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4111473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopianbool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, 4121473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian GLint w, GLint h, ogles_context_t* c) 4131473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian{ 4141473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian // quickly process empty rects 4151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian if ((w|h) <= 0) { 4161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return true; 4171473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 41803a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian if (!checkContext(c)) { 4191473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian return false; 4201473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian } 42103a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian texture_unit_t& u(c->textures.tmu[0]); 4221473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian EGLTextureObject* textureObject = u.texture; 42303a1b0116b115c214c16fa1a02a46999312fd0f2Mathias Agopian return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c); 4241473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} 4251473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 4261473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian} // namespace android 4271473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian 428