am 4d7fc365: Merge "remove copybit hack from software opengl (libagl)" into gingerbread
Merge commit '4d7fc3651bd93d588d2b8580010414b59bc67729' into gingerbread-plus-aosp * commit '4d7fc3651bd93d588d2b8580010414b59bc67729': remove copybit hack from software opengl (libagl)
This commit is contained in:
@@ -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 \
|
||||
@@ -51,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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -628,23 +628,6 @@ 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 +641,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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user