diff options
Diffstat (limited to 'opengl/libagl')
| -rw-r--r-- | opengl/libagl/Android.mk | 14 | ||||
| -rw-r--r-- | opengl/libagl/TextureObjectManager.cpp | 3 | ||||
| -rw-r--r-- | opengl/libagl/TextureObjectManager.h | 3 | ||||
| -rw-r--r-- | opengl/libagl/array.cpp | 13 | ||||
| -rw-r--r-- | opengl/libagl/copybit.cpp | 618 | ||||
| -rw-r--r-- | opengl/libagl/copybit.h | 75 | ||||
| -rw-r--r-- | opengl/libagl/egl.cpp | 143 | ||||
| -rw-r--r-- | opengl/libagl/state.cpp | 38 | ||||
| -rw-r--r-- | opengl/libagl/texture.cpp | 29 |
9 files changed, 55 insertions, 881 deletions
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk index 6cb146c06094..b5c018f46252 100644 --- a/opengl/libagl/Android.mk +++ b/opengl/libagl/Android.mk @@ -6,9 +6,6 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -# Set to 1 to use gralloc and copybits -LIBAGL_USE_GRALLOC_COPYBITS := 1 - LOCAL_SRC_FILES:= \ egl.cpp \ state.cpp \ @@ -37,6 +34,10 @@ ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -fstrict-aliasing endif +ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true) + LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER +endif + ifneq ($(TARGET_SIMULATOR),true) # we need to access the private Bionic header <bionic_tls.h> # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER @@ -47,13 +48,6 @@ ifneq ($(TARGET_SIMULATOR),true) LOCAL_C_INCLUDES += bionic/libc/private endif -ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1) - LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS - LOCAL_SRC_FILES += copybit.cpp - LOCAL_SHARED_LIBRARIES += libui -endif - - LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl LOCAL_MODULE:= libGLES_android diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp index 255ccac3565b..bbb82fc48a9c 100644 --- a/opengl/libagl/TextureObjectManager.cpp +++ b/opengl/libagl/TextureObjectManager.cpp @@ -55,9 +55,6 @@ void EGLTextureObject::init() memset(crop_rect, 0, sizeof(crop_rect)); generate_mipmap = GL_FALSE; direct = GL_FALSE; -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - try_copybit = false; -#endif // LIBAGL_USE_GRALLOC_COPYBITS buffer = 0; } diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h index 279e0406c212..70e3bef6e774 100644 --- a/opengl/libagl/TextureObjectManager.h +++ b/opengl/libagl/TextureObjectManager.h @@ -80,9 +80,6 @@ public: GLint crop_rect[4]; GLint generate_mipmap; GLint direct; -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - bool try_copybit; -#endif // LIBAGL_USE_GRALLOC_COPYBITS android_native_buffer_t* buffer; }; diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp index 71825c502a03..7fbe9b5f96ae 100644 --- a/opengl/libagl/array.cpp +++ b/opengl/libagl/array.cpp @@ -26,9 +26,6 @@ #include "primitives.h" #include "texture.h" #include "BufferObjectManager.h" -#ifdef LIBAGL_USE_GRALLOC_COPYBITS -#include "copybit.h" -#endif // LIBAGL_USE_GRALLOC_COPYBITS // ---------------------------------------------------------------------------- @@ -688,8 +685,8 @@ static void drawPrimitivesTriangleFanOrStrip(ogles_context_t* c, } while (num); } if (count) { - v0 = c->vc.vBuffer + 2 + num - 2; - v1 = c->vc.vBuffer + 2 + num - 1; + v0 = c->vc.vBuffer + 2 + vcs - 2; + v1 = c->vc.vBuffer + 2 + vcs - 1; if ((winding&2) == 0) { // for strips copy back the two last compiled vertices c->vc.vBuffer[0] = *v0; @@ -707,12 +704,6 @@ void drawPrimitivesTriangleStrip(ogles_context_t* c, void drawPrimitivesTriangleFan(ogles_context_t* c, GLint first, GLsizei count) { -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - if (drawTriangleFanWithCopybit(c, first, count)) { - return; - } -#endif // LIBAGL_USE_GRALLOC_COPYBITS - drawPrimitivesTriangleFanOrStrip(c, first, count, 2); } diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp deleted file mode 100644 index 67d1ce70be1a..000000000000 --- a/opengl/libagl/copybit.cpp +++ /dev/null @@ -1,618 +0,0 @@ -/* -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdlib.h> -#include <stdio.h> - -#include "context.h" -#include "fp.h" -#include "state.h" -#include "matrix.h" -#include "vertex.h" -#include "light.h" -#include "primitives.h" -#include "texture.h" -#include "BufferObjectManager.h" -#include "TextureObjectManager.h" - -#include <hardware/gralloc.h> -#include <hardware/copybit.h> -#include <private/ui/android_natives_priv.h> - -#include <ui/GraphicBuffer.h> -#include <ui/Region.h> -#include <ui/Rect.h> - - -#define DEBUG_COPYBIT false - -// ---------------------------------------------------------------------------- - -namespace android { - -static void textureToCopyBitImage( - const GGLSurface* surface, int32_t opFormat, - android_native_buffer_t* buffer, copybit_image_t* img) -{ - img->w = surface->stride; - img->h = surface->height; - img->format = opFormat; - img->base = surface->data; - img->handle = (native_handle_t *)buffer->handle; -} - -struct clipRectRegion : public copybit_region_t { - clipRectRegion(ogles_context_t* c) - { - scissor_t const* scissor = &c->rasterizer.state.scissor; - r.l = scissor->left; - r.t = scissor->top; - r.r = scissor->right; - r.b = scissor->bottom; - next = iterate; - } -private: - static int iterate(copybit_region_t const * self, copybit_rect_t* rect) { - *rect = static_cast<clipRectRegion const*>(self)->r; - const_cast<copybit_region_t *>(self)->next = iterate_done; - return 1; - } - static int iterate_done(copybit_region_t const *, copybit_rect_t*) { - return 0; - } -public: - copybit_rect_t r; -}; - -static bool supportedCopybitsFormat(int format) { - switch (format) { - case COPYBIT_FORMAT_RGBA_8888: - case COPYBIT_FORMAT_RGBX_8888: - case COPYBIT_FORMAT_RGB_888: - case COPYBIT_FORMAT_RGB_565: - case COPYBIT_FORMAT_BGRA_8888: - case COPYBIT_FORMAT_RGBA_5551: - case COPYBIT_FORMAT_RGBA_4444: - return true; - default: - return false; - } -} - -static bool hasAlpha(int format) { - switch (format) { - case COPYBIT_FORMAT_RGBA_8888: - case COPYBIT_FORMAT_BGRA_8888: - case COPYBIT_FORMAT_RGBA_5551: - case COPYBIT_FORMAT_RGBA_4444: - return true; - default: - return false; - } -} - -static inline int fixedToByte(GGLfixed val) { - return (val - (val >> 8)) >> 8; -} - -/** - * Performs a quick check of the rendering state. If this function returns - * false we cannot use the copybit driver. - */ - -static bool checkContext(ogles_context_t* c) { - - // By convention copybitQuickCheckContext() has already returned true. - // avoid checking the same information again. - - if (c->copybits.blitEngine == NULL) { - LOGD_IF(DEBUG_COPYBIT, "no copybit hal"); - return false; - } - - if (c->rasterizer.state.enables - & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) { - LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog"); - return false; - } - - // Note: The drawSurfaceBuffer is only set for destination - // surfaces types that are supported by the hardware and - // do not have an alpha channel. So we don't have to re-check that here. - - static const int tmu = 0; - texture_unit_t& u(c->textures.tmu[tmu]); - EGLTextureObject* textureObject = u.texture; - - if (!supportedCopybitsFormat(textureObject->surface.format)) { - LOGD_IF(DEBUG_COPYBIT, "texture format not supported"); - return false; - } - return true; -} - - -static bool copybit(GLint x, GLint y, - GLint w, GLint h, - EGLTextureObject* textureObject, - const GLint* crop_rect, - int transform, - ogles_context_t* c) -{ - status_t err = NO_ERROR; - - // We assume checkContext has already been called and has already - // returned true. - - const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; - - y = cbSurface.height - (y + h); - - const GLint Ucr = crop_rect[0]; - const GLint Vcr = crop_rect[1]; - const GLint Wcr = crop_rect[2]; - const GLint Hcr = crop_rect[3]; - - GLint screen_w = w; - GLint screen_h = h; - int32_t dsdx = Wcr << 16; // dsdx = ((Wcr/screen_w)/Wt)*Wt - int32_t dtdy = Hcr << 16; // dtdy = -((Hcr/screen_h)/Ht)*Ht - if (transform & COPYBIT_TRANSFORM_ROT_90) { - swap(screen_w, screen_h); - } - if (dsdx!=screen_w || dtdy!=screen_h) { - // in most cases the divide is not needed - dsdx /= screen_w; - dtdy /= screen_h; - } - dtdy = -dtdy; // see equation of dtdy above - - // copybit doesn't say anything about filtering, so we can't - // discriminate. On msm7k, copybit will always filter. - // the code below handles min/mag filters, we keep it as a reference. - -#ifdef MIN_MAG_FILTER - int32_t texelArea = gglMulx(dtdy, dsdx); - if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) { - // Non-linear filtering on a texture enlargement. - LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR"); - return false; - } - if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) { - // Non-linear filtering on an texture shrink. - LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR"); - return false; - } -#endif - - const uint32_t enables = c->rasterizer.state.enables; - int planeAlpha = 255; - bool alphaPlaneWorkaround = false; - static const int tmu = 0; - texture_t& tev(c->rasterizer.state.texture[tmu]); - int32_t opFormat = textureObject->surface.format; - const bool srcTextureHasAlpha = hasAlpha(opFormat); - if (!srcTextureHasAlpha) { - planeAlpha = fixedToByte(c->currentColorClamped.a); - } - - const bool cbHasAlpha = hasAlpha(cbSurface.format); - bool blending = false; - if ((enables & GGL_ENABLE_BLENDING) - && !(c->rasterizer.state.blend.src == GL_ONE - && c->rasterizer.state.blend.dst == GL_ZERO)) { - // Blending is OK if it is - // the exact kind of blending that the copybits hardware supports. - // Note: The hardware only supports - // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA, - // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA. - // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case, - // because the performance is worth it, even if the results are - // not correct. - if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA - || c->rasterizer.state.blend.src == GL_ONE) - && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA - && c->rasterizer.state.blend.alpha_separate == 0)) { - // Incompatible blend mode. - LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode"); - return false; - } - blending = true; - } else { - if (cbHasAlpha) { - // NOTE: the result will be slightly wrong in this case because - // the destination alpha channel will be set to 1.0 instead of - // the iterated alpha value. *shrug*. - } - // disable plane blending and src blending for supported formats - planeAlpha = 255; - if (opFormat == COPYBIT_FORMAT_RGBA_8888) { - opFormat = COPYBIT_FORMAT_RGBX_8888; - } else { - if (srcTextureHasAlpha) { - LOGD_IF(DEBUG_COPYBIT, "texture format requires blending"); - return false; - } - } - } - - switch (tev.env) { - case GGL_REPLACE: - break; - case GGL_MODULATE: - // only cases allowed is: - // RGB source, color={1,1,1,a} -> can be done with GL_REPLACE - // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE - if (blending) { - if (c->currentColorClamped.r == c->currentColorClamped.a && - c->currentColorClamped.g == c->currentColorClamped.a && - c->currentColorClamped.b == c->currentColorClamped.a) { - // TODO: RGBA source, color={1,1,1,a} / regular-blending - // is equivalent - alphaPlaneWorkaround = true; - break; - } - } - LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE"); - return false; - default: - // Incompatible texture environment. - LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment"); - return false; - } - - copybit_device_t* copybit = c->copybits.blitEngine; - copybit_image_t src; - textureToCopyBitImage(&textureObject->surface, opFormat, - textureObject->buffer, &src); - copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr }; - - /* - * Below we perform extra passes needed to emulate things the h/w - * cannot do. - */ - - const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16); - const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16); - - sp<GraphicBuffer> tempBitmap; - - if (dsdx < maxScaleInv || dsdx > minScaleInv || - dtdy < maxScaleInv || dtdy > minScaleInv) - { - // The requested scale is out of the range the hardware - // can support. - LOGD_IF(DEBUG_COPYBIT, - "scale out of range dsdx=%08x (Wcr=%d / w=%d), " - "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", - dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); - - int32_t xscale=0x10000, yscale=0x10000; - if (dsdx > minScaleInv) xscale = c->copybits.minScale; - else if (dsdx < maxScaleInv) xscale = c->copybits.maxScale; - if (dtdy > minScaleInv) yscale = c->copybits.minScale; - else if (dtdy < maxScaleInv) yscale = c->copybits.maxScale; - dsdx = gglMulx(dsdx, xscale); - dtdy = gglMulx(dtdy, yscale); - - /* we handle only one step of resizing below. Handling an arbitrary - * number is relatively easy (replace "if" above by "while"), but requires - * two intermediate buffers and so far we never had the need. - */ - - if (dsdx < maxScaleInv || dsdx > minScaleInv || - dtdy < maxScaleInv || dtdy > minScaleInv) { - LOGD_IF(DEBUG_COPYBIT, - "scale out of range dsdx=%08x (Wcr=%d / w=%d), " - "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d", - dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr); - return false; - } - - const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16); - const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16); - - LOGD_IF(DEBUG_COPYBIT, - "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d", - xscale, yscale, dsdx, dtdy, tmp_w, tmp_h); - - tempBitmap = new GraphicBuffer( - tmp_w, tmp_h, src.format, - GraphicBuffer::USAGE_HW_2D); - - err = tempBitmap->initCheck(); - if (err == NO_ERROR) { - copybit_image_t tmp_dst; - copybit_rect_t tmp_rect; - tmp_dst.w = tmp_w; - tmp_dst.h = tmp_h; - tmp_dst.format = tempBitmap->format; - tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle; - tmp_rect.l = 0; - tmp_rect.t = 0; - tmp_rect.r = tmp_dst.w; - tmp_rect.b = tmp_dst.h; - region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmp_dst, &src, &tmp_rect, &srect, &tmp_it); - src = tmp_dst; - srect = tmp_rect; - } - } - - copybit_image_t dst; - textureToCopyBitImage(&cbSurface, cbSurface.format, - c->copybits.drawSurfaceBuffer, &dst); - copybit_rect_t drect = {x, y, x+w, y+h}; - - - /* and now the alpha-plane hack. This handles the "Fade" case of a - * texture with an alpha channel. - */ - if (alphaPlaneWorkaround) { - sp<GraphicBuffer> tempCb = new GraphicBuffer( - w, h, COPYBIT_FORMAT_RGB_565, - GraphicBuffer::USAGE_HW_2D); - - err = tempCb->initCheck(); - - copybit_image_t tmpCbImg; - copybit_rect_t tmpCbRect; - copybit_rect_t tmpdrect = drect; - tmpCbImg.w = w; - tmpCbImg.h = h; - tmpCbImg.format = tempCb->format; - tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle; - tmpCbRect.l = 0; - tmpCbRect.t = 0; - - if (drect.l < 0) { - tmpCbRect.l = -tmpdrect.l; - tmpdrect.l = 0; - } - if (drect.t < 0) { - tmpCbRect.t = -tmpdrect.t; - tmpdrect.t = 0; - } - if (drect.l + tmpCbImg.w > dst.w) { - tmpCbImg.w = dst.w - drect.l; - tmpdrect.r = dst.w; - } - if (drect.t + tmpCbImg.h > dst.h) { - tmpCbImg.h = dst.h - drect.t; - tmpdrect.b = dst.h; - } - - tmpCbRect.r = tmpCbImg.w; - tmpCbRect.b = tmpCbImg.h; - - if (!err) { - // first make a copy of the destination buffer - region_iterator tmp_it(Region(Rect(w, h))); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE); - err = copybit->stretch(copybit, - &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it); - } - if (!err) { - // then proceed as usual, but without the alpha plane - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (enables & GGL_ENABLE_DITHER) ? - COPYBIT_ENABLE : COPYBIT_DISABLE); - clipRectRegion it(c); - err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - } - if (!err) { - // finally copy back the destination on top with 1-alphaplane - int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a); - clipRectRegion it(c); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE); - err = copybit->stretch(copybit, - &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it); - } - } else { - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (enables & GGL_ENABLE_DITHER) ? - COPYBIT_ENABLE : COPYBIT_DISABLE); - clipRectRegion it(c); - - LOGD_IF(0, - "dst={%d, %d, %d, %p, %p}, " - "src={%d, %d, %d, %p, %p}, " - "drect={%d,%d,%d,%d}, " - "srect={%d,%d,%d,%d}, " - "it={%d,%d,%d,%d}, " , - dst.w, dst.h, dst.format, dst.base, dst.handle, - src.w, src.h, src.format, src.base, src.handle, - drect.l, drect.t, drect.r, drect.b, - srect.l, srect.t, srect.r, srect.b, - it.r.l, it.r.t, it.r.r, it.r.b - ); - - err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it); - } - if (err != NO_ERROR) { - c->textures.tmu[0].texture->try_copybit = false; - } - return err == NO_ERROR ? true : false; -} - -/* - * Try to draw a triangle fan with copybit, return false if we fail. - */ -bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count) -{ - if (!checkContext(c)) { - return false; - } - - // FIXME: we should handle culling here - c->arrays.compileElements(c, c->vc.vBuffer, 0, 4); - - // we detect if we're dealing with a rectangle, by comparing the - // rectangles {v0,v2} and {v1,v3} which should be identical. - - // NOTE: we should check that the rectangle is window aligned, however - // if we do that, the optimization won't be taken in a lot of cases. - // Since this code is intended to be used with SurfaceFlinger only, - // so it's okay... - - const vec4_t& v0 = c->vc.vBuffer[0].window; - const vec4_t& v1 = c->vc.vBuffer[1].window; - const vec4_t& v2 = c->vc.vBuffer[2].window; - const vec4_t& v3 = c->vc.vBuffer[3].window; - int l = min(v0.x, v2.x); - int b = min(v0.y, v2.y); - int r = max(v0.x, v2.x); - int t = max(v0.y, v2.y); - if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) || - (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) { - LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle"); - return false; - } - - // fetch and transform texture coordinates - // NOTE: maybe it would be better to have a "compileElementsAll" method - // that would ensure all vertex data are fetched and transformed - const transform_t& tr = c->transforms.texture[0].transform; - for (size_t i=0 ; i<4 ; i++) { - const GLubyte* tp = c->arrays.texture[0].element(i); - vertex_t* const v = &c->vc.vBuffer[i]; - c->arrays.texture[0].fetch(c, v->texture[0].v, tp); - // FIXME: we should bail if q!=1 - c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]); - } - - const vec4_t& t0 = c->vc.vBuffer[0].texture[0]; - const vec4_t& t1 = c->vc.vBuffer[1].texture[0]; - const vec4_t& t2 = c->vc.vBuffer[2].texture[0]; - const vec4_t& t3 = c->vc.vBuffer[3].texture[0]; - int txl = min(t0.x, t2.x); - int txb = min(t0.y, t2.y); - int txr = max(t0.x, t2.x); - int txt = max(t0.y, t2.y); - if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) || - (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) { - LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle"); - return false; - } - if ((txl != 0) || (txb != 0) || - (txr != FIXED_ONE) || (txt != FIXED_ONE)) { - // we could probably handle this case, if we wanted to - LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x", - txl, txb, txr, txt); - return false; - } - - // at this point, we know we are dealing with a rectangle, so we - // only need to consider 3 vertices for computing the jacobians - - const int dx01 = v1.x - v0.x; - const int dx02 = v2.x - v0.x; - const int dy01 = v1.y - v0.y; - const int dy02 = v2.y - v0.y; - const int ds01 = t1.S - t0.S; - const int ds02 = t2.S - t0.S; - const int dt01 = t1.T - t0.T; - const int dt02 = t2.T - t0.T; - const int area = dx01*dy02 - dy01*dx02; - int dsdx, dsdy, dtdx, dtdy; - if (area >= 0) { - dsdx = ds01*dy02 - ds02*dy01; - dtdx = dt01*dy02 - dt02*dy01; - dsdy = ds02*dx01 - ds01*dx02; - dtdy = dt02*dx01 - dt01*dx02; - } else { - dsdx = ds02*dy01 - ds01*dy02; - dtdx = dt02*dy01 - dt01*dy02; - dsdy = ds01*dx02 - ds02*dx01; - dtdy = dt01*dx02 - dt02*dx01; - } - - // here we rely on the fact that we know the transform is - // a rigid-body transform AND that it can only rotate in 90 degrees - // increments - - int transform = 0; - if (dsdx == 0) { - // 90 deg rotation case - // [ 0 dtdx ] - // [ dsdx 0 ] - transform |= COPYBIT_TRANSFORM_ROT_90; - // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted - if (dtdx > 0) - transform |= COPYBIT_TRANSFORM_FLIP_H; - if (dsdy < 0) - transform |= COPYBIT_TRANSFORM_FLIP_V; - } else { - // [ dsdx 0 ] - // [ 0 dtdy ] - if (dsdx < 0) - transform |= COPYBIT_TRANSFORM_FLIP_H; - if (dtdy < 0) - transform |= COPYBIT_TRANSFORM_FLIP_V; - } - - //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform); - //LOGD("A=%f\tB=%f\nC=%f\tD=%f", - // dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0); - - int x = l >> 4; - int y = b >> 4; - int w = (r-l) >> 4; - int h = (t-b) >> 4; - texture_unit_t& u(c->textures.tmu[0]); - EGLTextureObject* textureObject = u.texture; - GLint tWidth = textureObject->surface.width; - GLint tHeight = textureObject->surface.height; - GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight}; - const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s; - y = cbSurface.height - (y + h); - return copybit(x, y, w, h, textureObject, crop_rect, transform, c); -} - -/* - * Try to drawTexiOESWithCopybit, return false if we fail. - */ - -bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, - GLint w, GLint h, ogles_context_t* c) -{ - // quickly process empty rects - if ((w|h) <= 0) { - return true; - } - if (!checkContext(c)) { - return false; - } - texture_unit_t& u(c->textures.tmu[0]); - EGLTextureObject* textureObject = u.texture; - return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c); -} - -} // namespace android - diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h deleted file mode 100644 index b8b5afda2656..000000000000 --- a/opengl/libagl/copybit.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -** -** Copyright 2009, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_OPENGLES_COPYBIT_H -#define ANDROID_OPENGLES_COPYBIT_H - -#include <stdlib.h> - -#include <GLES/gl.h> - -#include "TextureObjectManager.h" -namespace android { -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - -bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z, - GLint w, GLint h, ogles_context_t* c); - -bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, - GLsizei count); - -inline bool copybitQuickCheckContext(ogles_context_t* c) { - return c->copybits.drawSurfaceBuffer != 0 - && c->rasterizer.state.enabled_tmu == 1 - && c->textures.tmu[0].texture->try_copybit; -} - -/* - * Tries to draw a drawTexiOES using copybit hardware. - * Returns true if successful. - */ -inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z, - GLint w, GLint h, ogles_context_t* c) { - if (!copybitQuickCheckContext(c)) { - return false; - } - - return drawTexiOESWithCopybit_impl(x, y, z, w, h, c); -} - -/* - * Tries to draw a triangle fan using copybit hardware. - * Returns true if successful. - */ -inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first, - GLsizei count) { - /* - * We are looking for the glDrawArrays call made by SurfaceFlinger. - */ - - if ((count!=4) || first || !copybitQuickCheckContext(c)) - return false; - - return drawTriangleFanWithCopybit_impl(c, first, count); -} - - -#endif // LIBAGL_USE_GRALLOC_COPYBITS - -} // namespace android - -#endif // ANDROID_OPENGLES_COPYBIT_H diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index b6e0aae74ee8..163b2dbcd3a4 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -158,7 +158,6 @@ struct egl_surface_t virtual EGLint getSwapBehavior() const; virtual EGLBoolean swapBuffers(); virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); - virtual EGLClientBuffer getRenderBuffer() const; protected: GGLSurface depth; }; @@ -202,9 +201,6 @@ EGLBoolean egl_surface_t::setSwapRectangle( { return EGL_FALSE; } -EGLClientBuffer egl_surface_t::getRenderBuffer() const { - return 0; -} // ---------------------------------------------------------------------------- @@ -213,7 +209,7 @@ struct egl_window_surface_v2_t : public egl_surface_t egl_window_surface_v2_t( EGLDisplay dpy, EGLConfig config, int32_t depthFormat, - android_native_window_t* window); + ANativeWindow* window); ~egl_window_surface_v2_t(); @@ -230,12 +226,11 @@ struct egl_window_surface_v2_t : public egl_surface_t virtual EGLint getRefreshRate() const; virtual EGLint getSwapBehavior() const; virtual EGLBoolean setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h); - virtual EGLClientBuffer getRenderBuffer() const; private: status_t lock(android_native_buffer_t* buf, int usage, void** vaddr); status_t unlock(android_native_buffer_t* buf); - android_native_window_t* nativeWindow; + ANativeWindow* nativeWindow; android_native_buffer_t* buffer; android_native_buffer_t* previousBuffer; gralloc_module_t const* module; @@ -355,7 +350,7 @@ private: egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat, - android_native_window_t* window) + ANativeWindow* window) : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0), previousBuffer(0), module(0), blitengine(0), bits(NULL) @@ -576,41 +571,44 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() buffer = 0; // dequeue a new buffer - nativeWindow->dequeueBuffer(nativeWindow, &buffer); - - // TODO: lockBuffer should rather be executed when the very first - // direct rendering occurs. - nativeWindow->lockBuffer(nativeWindow, buffer); - - // reallocate the depth-buffer if needed - if ((width != buffer->width) || (height != buffer->height)) { - // TODO: we probably should reset the swap rect here - // if the window size has changed - width = buffer->width; - height = buffer->height; - if (depth.data) { - free(depth.data); - depth.width = width; - depth.height = height; - depth.stride = buffer->stride; - depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); - if (depth.data == 0) { - setError(EGL_BAD_ALLOC, EGL_FALSE); - return EGL_FALSE; + if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) { + + // TODO: lockBuffer should rather be executed when the very first + // direct rendering occurs. + nativeWindow->lockBuffer(nativeWindow, buffer); + + // reallocate the depth-buffer if needed + if ((width != buffer->width) || (height != buffer->height)) { + // TODO: we probably should reset the swap rect here + // if the window size has changed + width = buffer->width; + height = buffer->height; + if (depth.data) { + free(depth.data); + depth.width = width; + depth.height = height; + depth.stride = buffer->stride; + depth.data = (GGLubyte*)malloc(depth.stride*depth.height*2); + if (depth.data == 0) { + setError(EGL_BAD_ALLOC, EGL_FALSE); + return EGL_FALSE; + } } } - } - - // keep a reference on the buffer - buffer->common.incRef(&buffer->common); - // finally pin the buffer down - if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | - GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { - LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", - buffer, buffer->width, buffer->height); - return setError(EGL_BAD_ACCESS, EGL_FALSE); - // FIXME: we should make sure we're not accessing the buffer anymore + // keep a reference on the buffer + buffer->common.incRef(&buffer->common); + + // finally pin the buffer down + if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | + GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) { + LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)", + buffer, buffer->width, buffer->height); + return setError(EGL_BAD_ACCESS, EGL_FALSE); + // FIXME: we should make sure we're not accessing the buffer anymore + } + } else { + return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE); } return EGL_TRUE; @@ -623,28 +621,6 @@ EGLBoolean egl_window_surface_v2_t::setSwapRectangle( return EGL_TRUE; } -EGLClientBuffer egl_window_surface_v2_t::getRenderBuffer() const -{ - return buffer; -} - -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - -static bool supportedCopybitsDestinationFormat(int format) { - // Hardware supported - switch (format) { - case HAL_PIXEL_FORMAT_RGB_565: - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - case HAL_PIXEL_FORMAT_RGBA_4444: - case HAL_PIXEL_FORMAT_RGBA_5551: - case HAL_PIXEL_FORMAT_BGRA_8888: - return true; - } - return false; -} -#endif - EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) { GGLSurface buffer; @@ -658,18 +634,6 @@ EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl) if (depth.data != gl->rasterizer.state.buffers.depth.data) gl->rasterizer.procs.depthBuffer(gl, &depth); -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - gl->copybits.drawSurfaceBuffer = 0; - if (gl->copybits.blitEngine != NULL) { - if (supportedCopybitsDestinationFormat(buffer.format)) { - buffer_handle_t handle = this->buffer->handle; - if (handle != NULL) { - gl->copybits.drawSurfaceBuffer = this->buffer; - } - } - } -#endif // LIBAGL_USE_GRALLOC_COPYBITS - return EGL_TRUE; } EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl) @@ -883,7 +847,6 @@ static char const * const gExtensionsString = // "KHR_image_pixmap " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " - "EGL_ANDROID_get_render_buffer " ; // ---------------------------------------------------------------------------- @@ -936,8 +899,6 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, { "eglSetSwapRectangleANDROID", (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, - { "eglGetRenderBufferANDROID", - (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, }; /* @@ -1300,7 +1261,7 @@ static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, if (!(surfaceType & EGL_WINDOW_BIT)) return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); - if (static_cast<android_native_window_t*>(window)->common.magic != + if (static_cast<ANativeWindow*>(window)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } @@ -1323,7 +1284,7 @@ static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config, egl_surface_t* surface; surface = new egl_window_surface_v2_t(dpy, config, depthFormat, - static_cast<android_native_window_t*>(window)); + static_cast<ANativeWindow*>(window)); if (!surface->initCheck()) { // there was a problem in the ctor, the error @@ -1525,8 +1486,13 @@ EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list, } if (ggl_unlikely(attrib_list==0)) { - *num_config = 0; - return EGL_TRUE; + /* + * A NULL attrib_list should be treated as though it was an empty + * one (terminated with EGL_NONE) as defined in + * section 3.4.1 "Querying Configurations" in the EGL specification. + */ + static const EGLint dummy = EGL_NONE; + attrib_list = &dummy; } int numAttributes = 0; @@ -2150,18 +2116,3 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, return EGL_TRUE; } - -EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw) -{ - if (egl_display_t::is_valid(dpy) == EGL_FALSE) - return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0); - - egl_surface_t* d = static_cast<egl_surface_t*>(draw); - if (!d->isValid()) - return setError(EGL_BAD_SURFACE, (EGLClientBuffer)0); - if (d->dpy != dpy) - return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0); - - // post the surface - return d->getRenderBuffer(); -} diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp index 27bb5454fd57..a0f720a0d19b 100644 --- a/opengl/libagl/state.cpp +++ b/opengl/libagl/state.cpp @@ -28,10 +28,6 @@ #include "BufferObjectManager.h" #include "TextureObjectManager.h" -#ifdef LIBAGL_USE_GRALLOC_COPYBITS -#include <hardware/copybit.h> -#endif // LIBAGL_USE_GRALLOC_COPYBITS - namespace android { // ---------------------------------------------------------------------------- @@ -101,35 +97,6 @@ ogles_context_t *ogles_init(size_t extra) // OpenGL enables dithering by default c->rasterizer.procs.enable(c, GL_DITHER); - c->copybits.blitEngine = NULL; - c->copybits.minScale = 0; - c->copybits.maxScale = 0; - c->copybits.drawSurfaceBuffer = 0; - -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - hw_module_t const* module; - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - struct copybit_device_t* copyBits; - if (copybit_open(module, ©Bits) == 0) { - c->copybits.blitEngine = copyBits; - { - int minLim = copyBits->get(copyBits, - COPYBIT_MINIFICATION_LIMIT); - if (minLim != -EINVAL && minLim > 0) { - c->copybits.minScale = (1 << 16) / minLim; - } - } - { - int magLim = copyBits->get(copyBits, - COPYBIT_MAGNIFICATION_LIMIT); - if (magLim != -EINVAL && magLim > 0) { - c->copybits.maxScale = min(32*1024-1, magLim) << 16; - } - } - } - } -#endif // LIBAGL_USE_GRALLOC_COPYBITS - return c; } @@ -144,11 +111,6 @@ void ogles_uninit(ogles_context_t* c) c->bufferObjectManager->decStrong(c); ggl_uninit_context(&(c->rasterizer)); free(c->rasterizer.base); -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - if (c->copybits.blitEngine != NULL) { - copybit_close((struct copybit_device_t*) c->copybits.blitEngine); - } -#endif // LIBAGL_USE_GRALLOC_COPYBITS } void _ogles_error(ogles_context_t* c, GLenum error) diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp index 9407bd55305e..eb9689551fec 100644 --- a/opengl/libagl/texture.cpp +++ b/opengl/libagl/texture.cpp @@ -26,10 +26,6 @@ #include <private/ui/android_natives_priv.h> #include <ETC1/etc1.h> -#ifdef LIBAGL_USE_GRALLOC_COPYBITS -#include "copybit.h" -#endif // LIBAGL_USE_GRALLOC_COPYBITS - namespace android { // ---------------------------------------------------------------------------- @@ -763,17 +759,10 @@ static void drawTexxOESImp(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h, ogles_context_t* c) { -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - if (drawTexiOESWithCopybit(gglFixedToIntRound(x), - gglFixedToIntRound(y), gglFixedToIntRound(z), - gglFixedToIntRound(w), gglFixedToIntRound(h), c)) { - return; - } -#else // quickly reject empty rects if ((w|h) <= 0) return; -#endif + drawTexxOESImp(x, y, z, w, h, c); } @@ -785,11 +774,6 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte // which is a lot faster. if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) { -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - if (drawTexiOESWithCopybit(x, y, z, w, h, c)) { - return; - } -#endif const int tmu = 0; texture_unit_t& u(c->textures.tmu[tmu]); EGLTextureObject* textureObject = u.texture; @@ -797,9 +781,7 @@ static void drawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h, ogles_conte const GLint Hcr = textureObject->crop_rect[3]; if ((w == Wcr) && (h == -Hcr)) { -#ifndef LIBAGL_USE_GRALLOC_COPYBITS if ((w|h) <= 0) return; // quickly reject empty rects -#endif if (u.dirty) { c->rasterizer.procs.activeTexture(c, tmu); @@ -1515,7 +1497,7 @@ void glReadPixels( ogles_error(c, GL_INVALID_VALUE); return; } - if (x<0 || x<0) { + if (x<0 || y<0) { ogles_error(c, GL_INVALID_VALUE); return; } @@ -1646,13 +1628,6 @@ void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) // bind it to the texture unit sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c); tex->setImage(native_buffer); - -#ifdef LIBAGL_USE_GRALLOC_COPYBITS - tex->try_copybit = false; - if (c->copybits.blitEngine != NULL) { - tex->try_copybit = true; - } -#endif // LIBAGL_USE_GRALLOC_COPYBITS } void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) |
