GLExtras.cpp revision 9e3ead124cc10fcc888a8be7df9949d3d4ba1bb7
1/* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#define LOG_TAG "GLExtras" 27#define LOG_NDEBUG 1 28 29#include "config.h" 30 31#include "AndroidLog.h" 32#include "DrawExtra.h" 33#include "DrawQuadData.h" 34#include "GLExtras.h" 35#include "IntRect.h" 36#include "SkPath.h" 37#include "TilesManager.h" 38#include "android_graphics.h" 39 40// Touch ring border width. This is doubled if the ring is not pressed 41#define RING_BORDER_WIDTH 1 42 43GLExtras::GLExtras() 44 : m_drawExtra(0) 45 , m_visibleContentRect() 46{ 47} 48 49GLExtras::~GLExtras() 50{ 51} 52 53void GLExtras::drawRing(SkRect& srcRect, Color color, const TransformationMatrix* drawMat) 54{ 55 if (srcRect.fRight <= srcRect.fLeft || srcRect.fBottom <= srcRect.fTop) { 56 // Invalid rect, reject it 57 return; 58 } 59 ALOGV("drawQuad [%fx%f, %f, %f]", srcRect.fLeft, srcRect.fTop, 60 srcRect.width(), srcRect.height()); 61 // Pull the alpha out of the color so that the shader applies it correctly. 62 // Otherwise we either don't have blending enabled, or the alpha will get 63 // double applied 64 Color colorWithoutAlpha(0xFF000000 | color.rgb()); 65 float alpha = color.alpha() / (float) 255; 66 67 PureColorQuadData data(colorWithoutAlpha, drawMat ? LayerQuad : BaseQuad, 68 drawMat, &srcRect, alpha, false); 69 TilesManager::instance()->shader()->drawQuad(&data); 70} 71 72void GLExtras::drawRegion(const SkRegion& region, bool fill, bool drawBorder, 73 const TransformationMatrix* drawMat, Color color) 74{ 75 if (region.isEmpty()) 76 return; 77 if (fill) { 78 SkRegion::Iterator rgnIter(region); 79 while (!rgnIter.done()) { 80 const SkIRect& ir = rgnIter.rect(); 81 SkRect r; 82 r.set(ir.fLeft, ir.fTop, ir.fRight, ir.fBottom); 83 drawRing(r, color, drawMat); 84 rgnIter.next(); 85 } 86 } 87 if (fill && !drawBorder) 88 return; 89 SkPath path; 90 if (!region.getBoundaryPath(&path)) 91 return; 92 SkPath::Iter iter(path, true); 93 SkPath::Verb verb; 94 SkPoint pts[4]; 95 SkRegion clip; 96 SkIRect startRect; 97 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 98 if (verb == SkPath::kLine_Verb) { 99 SkRect r; 100 r.set(pts, 2); 101 SkIRect line; 102 int borderWidth = RING_BORDER_WIDTH; 103 if (!fill) 104 borderWidth *= 2; 105 line.fLeft = r.fLeft - borderWidth; 106 line.fRight = r.fRight + borderWidth; 107 line.fTop = r.fTop - borderWidth; 108 line.fBottom = r.fBottom + borderWidth; 109 if (clip.intersects(line)) { 110 clip.op(line, SkRegion::kReverseDifference_Op); 111 if (clip.isEmpty()) 112 continue; // Nothing to draw, continue 113 line = clip.getBounds(); 114 if (SkIRect::Intersects(startRect, line)) { 115 clip.op(startRect, SkRegion::kDifference_Op); 116 if (clip.isEmpty()) 117 continue; // Nothing to draw, continue 118 line = clip.getBounds(); 119 } 120 } else { 121 clip.setRect(line); 122 } 123 r.set(line.fLeft, line.fTop, line.fRight, line.fBottom); 124 drawRing(r, color, drawMat); 125 if (startRect.isEmpty()) { 126 startRect.set(line.fLeft, line.fTop, line.fRight, line.fBottom); 127 } 128 } 129 if (verb == SkPath::kMove_Verb) { 130 startRect.setEmpty(); 131 } 132 } 133} 134 135void GLExtras::drawGL(const LayerAndroid* layer) 136{ 137 if (m_drawExtra) 138 m_drawExtra->drawGL(this, layer); 139} 140