bool IndependentBlocks::splitExitBlock(Region *R) { // Split the exit BB to place the load instruction of escaped users. BasicBlock *ExitBB = R->getExit(); Region *ExitRegion = RI->getRegionFor(ExitBB); if (ExitBB != ExitRegion->getEntry()) return false; BasicBlock *NewExit = createSingleExitEdge(R, this); std::vector<Region *> toUpdate; toUpdate.push_back(R); while (!toUpdate.empty()) { Region *Reg = toUpdate.back(); toUpdate.pop_back(); for (Region::iterator I = Reg->begin(), E = Reg->end(); I != E; ++I) { Region *SubR = *I; if (SubR->getExit() == ExitBB) toUpdate.push_back(SubR); } Reg->replaceExit(NewExit); } RI->setRegionFor(NewExit, R->getParent()); return true; }
// Print the cluster of the subregions. This groups the single basic blocks // and adds a different background color for each group. static void printRegionCluster(const Region &R, GraphWriter<RegionInfo *> &GW, unsigned depth = 0) { raw_ostream &O = GW.getOStream(); O.indent(2 * depth) << "subgraph cluster_" << static_cast<const void*>(&R) << " {\n"; O.indent(2 * (depth + 1)) << "label = \"\";\n"; if (!onlySimpleRegions || R.isSimple()) { O.indent(2 * (depth + 1)) << "style = filled;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 1) << "\n"; } else { O.indent(2 * (depth + 1)) << "style = solid;\n"; O.indent(2 * (depth + 1)) << "color = " << ((R.getDepth() * 2 % 12) + 2) << "\n"; } for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) printRegionCluster(**RI, GW, depth + 1); const RegionInfo &RI = *static_cast<const RegionInfo*>(R.getRegionInfo()); for (auto *BB : R.blocks()) if (RI.getRegionFor(BB) == &R) O.indent(2 * (depth + 1)) << "Node" << static_cast<const void*>(RI.getTopLevelRegion()->getBBNode(BB)) << ";\n"; O.indent(2 * depth) << "}\n"; }
void nextStep( GridType *grid, const Region<Topology::DIM>& validRegion, const CoordType& globalDimensions, unsigned step, SteererEvent event, std::size_t rank, bool lastCall, SteererFeedback *feedback) { if (waterAvailable && (trigger->averageTemperature() > 250)) { std::cout << "WARNING---------------------------------------------------\n" << "WARNING: initiating rain at time step " << step << "\n" << "WARNING---------------------------------------------------\n"; for (Region<Topology::DIM>::Iterator i = validRegion.begin(); i != validRegion.end(); ++i) { BushFireCell cell = grid->get(*i); if ((cell.fuel > 0) && (cell.temperature > 0.0001)) { cell.humidity += 0.5; } grid->set(*i, cell); } if (lastCall) { waterAvailable = 0; } } }
int Board::count(const Region& ss, const Piece &value) const { register int result = 0; for (auto s = ss.begin(); s != ss.end(); s++) if (at(s->file(),s->rank()) == value) result++; return result; }
void polly::simplifyRegion(Scop *S, Pass *P) { Region *R = &S->getRegion(); // Create single entry edge if the region has multiple entry edges. if (!R->getEnteringBlock()) { BasicBlock *OldEntry = R->getEntry(); BasicBlock *NewEntry = SplitBlock(OldEntry, OldEntry->begin(), P); for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI) if ((*SI)->getBasicBlock() == OldEntry) { (*SI)->setBasicBlock(NewEntry); break; } R->replaceEntryRecursive(NewEntry); } // Create single exit edge if the region has multiple exit edges. if (!R->getExitingBlock()) { BasicBlock *NewExit = createSingleExitEdge(R, P); for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI) (*RI)->replaceExitRecursive(NewExit); } }
void ji_move_region(const Region& region, int dx, int dy) { size_t nrects = region.size(); // Blit directly screen to screen. if (is_linear_bitmap(ji_screen) && nrects == 1) { Rect rc = region[0]; blit(ji_screen, ji_screen, rc.x, rc.y, rc.x+dx, rc.y+dy, rc.w, rc.h); } // Blit saving areas and copy them. else if (nrects > 1) { std::vector<BITMAP*> images(nrects); Region::const_iterator it, begin=region.begin(), end=region.end(); BITMAP* bmp; int c; for (c=0, it=begin; it != end; ++it, ++c) { const Rect& rc = *it; bmp = create_bitmap(rc.w, rc.h); blit(ji_screen, bmp, rc.x, rc.y, 0, 0, bmp->w, bmp->h); images[c] = bmp; } for (c=0, it=begin; it != end; ++it, ++c) { const Rect& rc = *it; bmp = images[c]; blit(bmp, ji_screen, 0, 0, rc.x+dx, rc.y+dy, bmp->w, bmp->h); destroy_bitmap(bmp); } } }
TEST(Region, Iterators) { Region a; a.createUnion(a, Region(Rect(0, 0, 32, 64))); a.createUnion(a, Region(Rect(0, 0, 64, 32))); int c = 0; for (Region::iterator it=a.begin(), end=a.end(); it!=end; ++it) { ++c; } EXPECT_EQ(2, c); c = 0; for (Region::const_iterator it=a.begin(), end=a.end(); it!=end; ++it) { ++c; } EXPECT_EQ(2, c); }
/* * Clear Region implementation for C2D/MDP versions. * * @param: region to be cleared * @param: EGL Display * @param: EGL Surface * * @return 0 on success */ int qcomuiClearRegion(Region region, EGLDisplay dpy, EGLSurface sur) { int ret = 0; if (-1 == sCompositionType) { sCompositionType = getCompositionType(); } if ((COMPOSITION_TYPE_MDP != sCompositionType) && (COMPOSITION_TYPE_C2D != sCompositionType) && #ifdef USE_MDP3 (COMPOSITION_TYPE_DYN != sCompositionType) && #endif (COMPOSITION_TYPE_CPU != sCompositionType)) { // For non CPU/C2D/MDP composition, return an error, so that SF can use // the GPU to draw the wormhole. return -1; } android_native_buffer_t *renderBuffer = (android_native_buffer_t *) eglGetRenderBufferANDROID(dpy, sur); if (!renderBuffer) { LOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", __FUNCTION__); return -1; } private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle; if(!fbHandle) { LOGE("%s: Framebuffer handle is NULL", __FUNCTION__); return -1; } int bytesPerPixel = 4; if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) { bytesPerPixel = 2; } Region::const_iterator it = region.begin(); Region::const_iterator const end = region.end(); const int32_t stride = renderBuffer->stride*bytesPerPixel; while (it != end) { const Rect& r = *it++; uint8_t* dst = (uint8_t*) fbHandle->base + (r.left + r.top*renderBuffer->stride)*bytesPerPixel; int w = r.width()*bytesPerPixel; int h = r.height(); do { if(4 == bytesPerPixel) android_memset32((uint32_t*)dst, 0, w); else android_memset16((uint16_t*)dst, 0, w); dst += stride; } while(--h); } return 0; }
//40641 for 3D void LayerBase::drawNormal(const Region& clip ,uint32_t fbHeight ,uint8_t eType ) const { struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; if(ISurfaceComposer::eLayerSideBySide == eType) { texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 0.5; texCoords[2].v = 0; texCoords[3].u = 0.5; texCoords[3].v = 1; } else if (ISurfaceComposer::eLayerTopAndBottom == eType) { texCoords[0].v = 0.5; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 0.5; } else { texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor((r.left), sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } }
int CBUtils::qcomuiClearRegion(Region region, EGLDisplay dpy){ int ret = 0; int compositionType = QCCompositionType::getInstance().getCompositionType(); if ((compositionType == COMPOSITION_TYPE_GPU) || sGPUlayerpresent) { //return ERROR when GPU composition is used or any layer is flagged //for GPU composition. return -1; } android_native_buffer_t *renderBuffer = qdutils::eglHandles::getInstance().getAndroidNativeRenderBuffer(dpy); if (!renderBuffer) { ALOGE("%s: eglGetRenderBufferANDROID returned NULL buffer", __FUNCTION__); return -1; } private_handle_t *fbHandle = (private_handle_t *)renderBuffer->handle; if(!fbHandle) { ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__); return -1; } int bytesPerPixel = 4; if (HAL_PIXEL_FORMAT_RGB_565 == fbHandle->format) { bytesPerPixel = 2; } Region::const_iterator it = region.begin(); Region::const_iterator const end = region.end(); const int32_t stride = renderBuffer->stride*bytesPerPixel; while (it != end) { const Rect& r = *it++; uint8_t* dst = (uint8_t*) fbHandle->base + (r.left + r.top*renderBuffer->stride)*bytesPerPixel; int w = r.width()*bytesPerPixel; int h = r.height(); do { if(4 == bytesPerPixel){ android_memset32((uint32_t*)dst, 0, w); } else { android_memset16((uint16_t*)dst, 0, w); } dst += stride; } while(--h); } return 0; }
AdjacencyPtr getAdjacency(const Region<1>& region) const { AdjacencyPtr adjacency(new RegionBasedAdjacency()); for (Region<1>::Iterator i = region.begin(); i != region.end(); ++i) { std::vector<int> neighbors = genNeighborList(i->x()); for (auto&& neighbor: neighbors) { adjacency->insert(i->x(), neighbor); } } return adjacency; }
void move_region(Manager* manager, const Region& region, int dx, int dy) { she::System* system = she::instance(); she::Display* display = Manager::getDefault()->getDisplay(); ASSERT(display); if (!display) return; she::ScopedSurfaceLock lock(display->getSurface()); std::size_t nrects = region.size(); // Blit directly screen to screen. if (nrects == 1) { gfx::Rect rc = region[0]; lock->scrollTo(rc, dx, dy); rc.offset(dx, dy); Manager::getDefault()->dirtyRect(rc); } // Blit saving areas and copy them. else if (nrects > 1) { std::vector<she::Surface*> images(nrects); Region::const_iterator it, begin=region.begin(), end=region.end(); she::Surface* sur; int c; for (c=0, it=begin; it != end; ++it, ++c) { const Rect& rc = *it; sur = system->createSurface(rc.w, rc.h); { she::ScopedSurfaceLock surlock(sur); lock->blitTo(surlock, rc.x, rc.y, 0, 0, rc.w, rc.h); } images[c] = sur; } for (c=0, it=begin; it != end; ++it, ++c) { gfx::Rect rc((*it).x+dx, (*it).y+dy, (*it).w, (*it).h); sur = images[c]; { she::ScopedSurfaceLock surlock(sur); surlock->blitTo(lock, 0, 0, rc.x, rc.y, rc.w, rc.h); manager->dirtyRect(rc); } sur->dispose(); } } }
void Region::replaceExitRecursive(BasicBlock *NewExit) { std::vector<Region *> RegionQueue; BasicBlock *OldExit = getExit(); RegionQueue.push_back(this); while (!RegionQueue.empty()) { Region *R = RegionQueue.back(); RegionQueue.pop_back(); R->replaceExit(NewExit); for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI) if ((*RI)->getExit() == OldExit) RegionQueue.push_back(*RI); } }
/** * Creates a new region with the same data as the argument, but divides rectangles as necessary to * remove T-Junctions * * Note: the output will not necessarily be a very efficient representation of the region, since it * may be that a triangle-based approach would generate significantly simpler geometry */ Region Region::createTJunctionFreeRegion(const Region& r) { if (r.isEmpty()) return r; if (r.isRect()) return r; Vector<Rect> reversed; reverseRectsResolvingJunctions(r.begin(), r.end(), reversed, direction_RTL); Region outputRegion; reverseRectsResolvingJunctions(reversed.begin(), reversed.end(), outputRegion.mStorage, direction_LTR); outputRegion.mStorage.add(r.getBounds()); // to make region valid, mStorage must end with bounds #if VALIDATE_REGIONS validate(outputRegion, "T-Junction free region"); #endif return outputRegion; }
Region Transform::transform(const Region& reg) const { Region out; if (CC_UNLIKELY(type() > TRANSLATE)) { if (CC_LIKELY(preserveRects())) { Region::const_iterator it = reg.begin(); Region::const_iterator const end = reg.end(); while (it != end) { out.orSelf(transform(*it++)); } } else { out.set(transform(reg.bounds())); } } else { int xpos = floorf(tx() + 0.5f); int ypos = floorf(ty() + 0.5f); out = reg.translate(xpos, ypos); } return out; }
void LayerBase::drawRegion(const Region& reg) const { Region::const_iterator it = reg.begin(); Region::const_iterator const end = reg.end(); if (it != end) { Rect r; const DisplayHardware& hw(graphicPlane(0).displayHardware()); const int32_t fbWidth = hw.getWidth(); const int32_t fbHeight = hw.getHeight(); const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, { fbWidth, fbHeight }, { 0, fbHeight } }; glVertexPointer(2, GL_SHORT, 0, vertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } }
AdjacencyPtr getAdjacency(const Region<1>& region) const { AdjacencyPtr adjacency(new RegionBasedAdjacency); for (Region<1>::Iterator i = region.begin(); i != region.end(); ++i) { int id = i->x(); int x = id % width(); int y = id / width(); int west = y * width() + (width() + x - 1) % width(); int east = y * width() + (width() + x + 1) % width(); int north = ((height() + y - 1) % height()) * width() + x; int south = ((height() + y + 1) % height()) * width() + x; adjacency->insert(id, west); adjacency->insert(id, east); adjacency->insert(id, north); adjacency->insert(id, south); } return adjacency; }
bool Region::validate(const Region& reg, const char* name) { bool result = true; const_iterator cur = reg.begin(); const_iterator const tail = reg.end(); const_iterator prev = cur++; Rect b(*prev); while (cur != tail) { b.left = b.left < cur->left ? b.left : cur->left; b.top = b.top < cur->top ? b.top : cur->top; b.right = b.right > cur->right ? b.right : cur->right; b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; if (cur->top == prev->top) { if (cur->bottom != prev->bottom) { LOGE("%s: invalid span %p", name, cur); result = false; } else if (cur->left < prev->right) { LOGE("%s: spans overlap horizontally prev=%p, cur=%p", name, prev, cur); result = false; } } else if (cur->top < prev->bottom) { LOGE("%s: spans overlap vertically prev=%p, cur=%p", name, prev, cur); result = false; } prev = cur; cur++; } if (b != reg.getBounds()) { result = false; LOGE("%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, b.left, b.top, b.right, b.bottom, reg.getBounds().left, reg.getBounds().top, reg.getBounds().right, reg.getBounds().bottom); } if (result == false) { reg.dump(name); } return result; }
void FGLWindowSurface::copyBlt( android_native_buffer_t *dst, void *dst_vaddr, android_native_buffer_t *src, const void *src_vaddr, const Region& clip) { // NOTE: dst and src must be the same format Region::const_iterator cur = clip.begin(); Region::const_iterator end = clip.end(); const size_t bpp = getBpp(src->format); const size_t dbpr = dst->stride * bpp; const size_t sbpr = src->stride * bpp; const uint8_t *const src_bits = (const uint8_t *)src_vaddr; uint8_t *const dst_bits = (uint8_t *)dst_vaddr; while (cur != end) { const Rect& r(*cur++); ssize_t w = r.right - r.left; ssize_t h = r.bottom - r.top; if (w <= 0 || h<=0) continue; size_t size = w * bpp; const uint8_t *s = src_bits + (r.left + src->stride * r.top) * bpp; uint8_t *d = dst_bits + (r.left + dst->stride * r.top) * bpp; if (dbpr==sbpr && size==sbpr) { size *= h; h = 1; } do { memcpy(d, s, size); d += dbpr; s += sbpr; } while (--h > 0); } }
void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); glColor4f(red,green,blue,alpha); glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); glEnable(GL_SCISSOR_TEST); glVertexPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } }
void Region::boolean_operation(int op, Region& dst, const Region& lhs, const Region& rhs, int dx, int dy) { #if VALIDATE_REGIONS validate(lhs, "boolean_operation (before): lhs"); validate(rhs, "boolean_operation (before): rhs"); validate(dst, "boolean_operation (before): dst"); #endif size_t lhs_count; Rect const * const lhs_rects = lhs.getArray(&lhs_count); size_t rhs_count; Rect const * const rhs_rects = rhs.getArray(&rhs_count); region_operator<Rect>::region lhs_region(lhs_rects, lhs_count); region_operator<Rect>::region rhs_region(rhs_rects, rhs_count, dx, dy); region_operator<Rect> operation(op, lhs_region, rhs_region); { // scope for rasterizer (dtor has side effects) rasterizer r(dst); operation(r); } #if VALIDATE_REGIONS validate(lhs, "boolean_operation: lhs"); validate(rhs, "boolean_operation: rhs"); validate(dst, "boolean_operation: dst"); #endif #if VALIDATE_WITH_CORECG SkRegion sk_lhs; SkRegion sk_rhs; SkRegion sk_dst; for (size_t i=0 ; i<lhs_count ; i++) sk_lhs.op( lhs_rects[i].left + dx, lhs_rects[i].top + dy, lhs_rects[i].right + dx, lhs_rects[i].bottom + dy, SkRegion::kUnion_Op); for (size_t i=0 ; i<rhs_count ; i++) sk_rhs.op( rhs_rects[i].left + dx, rhs_rects[i].top + dy, rhs_rects[i].right + dx, rhs_rects[i].bottom + dy, SkRegion::kUnion_Op); const char* name = "---"; SkRegion::Op sk_op; switch (op) { case op_or: sk_op = SkRegion::kUnion_Op; name="OR"; break; case op_and: sk_op = SkRegion::kIntersect_Op; name="AND"; break; case op_nand: sk_op = SkRegion::kDifference_Op; name="NAND"; break; } sk_dst.op(sk_lhs, sk_rhs, sk_op); if (sk_dst.isEmpty() && dst.isEmpty()) return; bool same = true; Region::const_iterator head = dst.begin(); Region::const_iterator const tail = dst.end(); SkRegion::Iterator it(sk_dst); while (!it.done()) { if (head != tail) { if ( head->left != it.rect().fLeft || head->top != it.rect().fTop || head->right != it.rect().fRight || head->bottom != it.rect().fBottom ) { same = false; break; } } else { same = false; break; } head++; it.next(); } if (head != tail) { same = false; } if(!same) { LOGD("---\nregion boolean %s failed", name); lhs.dump("lhs"); rhs.dump("rhs"); dst.dump("dst"); LOGD("should be"); SkRegion::Iterator it(sk_dst); while (!it.done()) { LOGD(" [%3d, %3d, %3d, %3d]", it.rect().fLeft, it.rect().fTop, it.rect().fRight, it.rect().fBottom); it.next(); } } #endif }
void LayerBase::drawTopAndBottom(const Region& clip ,uint32_t fbHeight ,uint8_t eType ) const { struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; GLfloat mVerticesCopy1[4][2]; GLfloat mVerticesCopy[4][2]; mVerticesCopy1[0][0] = mVertices[0][0]; mVerticesCopy1[0][1] = mVertices[0][1]; mVerticesCopy1[1][0] = mVertices[1][0]; mVerticesCopy1[1][1] = mVertices[1][1]; mVerticesCopy1[2][0] = mVertices[2][0]; mVerticesCopy1[2][1] = mVertices[2][1]; mVerticesCopy1[3][0] = mVertices[3][0]; mVerticesCopy1[3][1] = mVertices[3][1]; for (size_t i=0 ; i<4 ; i++){ mVerticesCopy1[i][1] /= 2; } mVerticesCopy[0][0] = mVerticesCopy1[0][0] ; mVerticesCopy[0][1] = mVerticesCopy1[0][1]+(fbHeight/2); mVerticesCopy[1][0] = mVerticesCopy1[1][0] ; mVerticesCopy[1][1] = mVerticesCopy1[1][1]+(fbHeight/2); mVerticesCopy[2][0] = mVerticesCopy1[2][0] ; mVerticesCopy[2][1] = mVerticesCopy1[2][1]+(fbHeight/2); mVerticesCopy[3][0] = mVerticesCopy1[3][0]; mVerticesCopy[3][1] = mVerticesCopy1[3][1]+(fbHeight/2); //3d surface if(ISurfaceComposer::eLayerTopAndBottom == eType) { //draw 3D buttom to FB buttom texCoords[0].u = 0; texCoords[0].v = 0.5; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 0.5; glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy1); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy/2, r.width(), r.height()/2); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0.5; texCoords[2].u = 1; texCoords[2].v = 0.5; texCoords[3].u = 1; texCoords[3].v = 1; glEnableClientState(GL_TEXTURE_COORD_ARRAY); //glVertexPointer(2, GL_FLOAT, 0, mVertices); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator itCopy1 = clip.begin(); Region::const_iterator const endCopy1 = clip.end(); while (itCopy1!= endCopy1) { const Rect& rCopy1 = *itCopy1++; const GLint syCopy1 = fbHeight - (rCopy1.top + rCopy1.height()); glScissor(rCopy1.left, syCopy1/2 + (fbHeight/2), rCopy1.width(), rCopy1.height()/2); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } else{ //draw 2D surface to buttom texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy1); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy/2, r.width(), r.height()/2); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } //draw 2D surface to top glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator itCopy = clip.begin(); Region::const_iterator const endCopy = clip.end(); while (itCopy!= endCopy) { const Rect& rCopy = *itCopy++; const GLint syCopy = fbHeight - (rCopy.top + rCopy.height()); glScissor(rCopy.left, syCopy/2 + (fbHeight/2), rCopy.width(), rCopy.height()/2); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } }
void LayerBase::drawSideBySide(const Region& clip ,uint32_t hw_w_half ,uint32_t fbHeight ,uint8_t eType ) const { struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; GLfloat mVerticesCopy1[4][2]; GLfloat mVerticesCopy[4][2]; mVerticesCopy1[0][0] = mVertices[0][0]; mVerticesCopy1[0][1] = mVertices[0][1]; mVerticesCopy1[1][0] = mVertices[1][0]; mVerticesCopy1[1][1] = mVertices[1][1]; mVerticesCopy1[2][0] = mVertices[2][0]; mVerticesCopy1[2][1] = mVertices[2][1]; mVerticesCopy1[3][0] = mVertices[3][0]; mVerticesCopy1[3][1] = mVertices[3][1]; for (size_t i=0 ; i<4 ; i++){ mVerticesCopy1[i][0] /= 2; } mVerticesCopy[0][0] = mVerticesCopy1[0][0] + hw_w_half; mVerticesCopy[0][1] = mVerticesCopy1[0][1]; mVerticesCopy[1][0] = mVerticesCopy1[1][0] + hw_w_half; mVerticesCopy[1][1] = mVerticesCopy1[1][1]; mVerticesCopy[2][0] = mVerticesCopy1[2][0] + hw_w_half; mVerticesCopy[2][1] = mVerticesCopy1[2][1]; mVerticesCopy[3][0] = mVerticesCopy1[3][0] + hw_w_half; mVerticesCopy[3][1] = mVerticesCopy1[3][1]; //3d surface LOGD("-------550-----Draw--in 3d surface --- mDrawingState.flags = %d", int(mDrawingState.flags)); if((ISurfaceComposer::eLayerSideBySide == eType)) { //draw 3D full to whole FB texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 0.5; texCoords[2].v = 0; texCoords[3].u = 0.5; texCoords[3].v = 1; glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy1); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left/2, sy, r.width()/2, r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } texCoords[0].u = 0.5; texCoords[0].v = 1; texCoords[1].u = 0.5; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; glEnableClientState(GL_TEXTURE_COORD_ARRAY); //glVertexPointer(2, GL_FLOAT, 0, mVertices); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator itCopy1 = clip.begin(); Region::const_iterator const endCopy1 = clip.end(); while (itCopy1!= endCopy1) { const Rect& rCopy1 = *itCopy1++; const GLint syCopy1 = fbHeight - (rCopy1.top + rCopy1.height()); glScissor(rCopy1.left/2+hw_w_half, syCopy1, rCopy1.width()/2, rCopy1.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } else{ //draw 2D surface to left texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy1); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left/2, sy, r.width()/2, r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } //draw 2D surface to right glVertexPointer(2, GL_FLOAT, 0, mVerticesCopy); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator itCopy = clip.begin(); Region::const_iterator const endCopy = clip.end(); while (itCopy!= endCopy) { const Rect& rCopy = *itCopy++; const GLint syCopy = fbHeight - (rCopy.top + rCopy.height()); glScissor(rCopy.left/2+hw_w_half, syCopy, rCopy.width()/2, rCopy.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } }
void LayerBlur::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); GLint X = x; GLint Y = fbHeight - (y + h); if (X < 0) { w += X; X = 0; } if (Y < 0) { h += Y; Y = 0; } if (w<0 || h<0) { // we're outside of the framebuffer return; } if (mTextureName == -1U) { // create the texture name the first time // can't do that in the ctor, because it runs in another thread. glGenTextures(1, &mTextureName); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType); if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) { mReadFormat = GL_RGBA; mReadType = GL_UNSIGNED_BYTE; mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888; } } Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); if (it != end) { #if defined(GL_OES_EGL_image_external) if (GLExtensions::getInstance().haveTextureExternal()) { glDisable(GL_TEXTURE_EXTERNAL_OES); } #endif glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); if (mRefreshCache) { mRefreshCache = false; mAutoRefreshPending = false; int32_t pixelSize = 4; int32_t s = w; if (mReadType == GL_UNSIGNED_SHORT_5_6_5) { // allocate enough memory for 4-bytes (2 pixels) aligned data s = (w + 1) & ~1; pixelSize = 2; } uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize); // This reads the frame-buffer, so a h/w GL would have to // finish() its rendering first. we don't want to do that // too often. Read data is 4-bytes aligned. glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels); // blur that texture. GGLSurface bl; bl.version = sizeof(GGLSurface); bl.width = w; bl.height = h; bl.stride = s; bl.format = mBlurFormat; bl.data = (GGLubyte*)pixels; blurFilter(&bl, 8, 2); if (GLExtensions::getInstance().haveNpot()) { glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / w; mHeightScale =-1.0f / h; mYOffset = 0; } else { GLuint tw = 1 << (31 - clz(w)); GLuint th = 1 << (31 - clz(h)); if (tw < GLuint(w)) tw <<= 1; if (th < GLuint(h)) th <<= 1; glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0, mReadFormat, mReadType, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / tw; mHeightScale =-1.0f / th; mYOffset = th-h; } free((void*)pixels); } const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); glColor4f(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glDisable(GL_BLEND); } if (mFlags & DisplayHardware::SLOW_CONFIG) { glDisable(GL_DITHER); } else { glEnable(GL_DITHER); } glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #ifdef AVOID_DRAW_TEXTURE if(UNLIKELY(transformed())) #endif { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(mWidthScale, mHeightScale, 1); glTranslatef(-x, mYOffset - y, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } #ifdef AVOID_DRAW_TEXTURE else{ Rect r; GLint crop[4] = { 0, 0, w, h }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); y = fbHeight - (y + h); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, w, h); } } #endif glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } }
void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; if (drawRotatedTexture) { int tWidth = mTransformedBounds.right - mTransformedBounds.left; int val = drawRotatedTexture(mOrientation, tWidth, fbHeight, clip, (GLfloat *) mVertices, (GLfloat *) texCoords); if (val == NO_ERROR) { return; } } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
bool Region::isTriviallyEqual(const Region& region) const { return begin() == region.begin(); }
void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture TextureManager::activateTexture(texture, needsFiltering()); uint32_t width = texture.width; uint32_t height = texture.height; GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; int renderEffect = mFlinger->getRenderEffect(); int renderColorR = mFlinger->getRenderColorR(); int renderColorG = mFlinger->getRenderColorG(); int renderColorB = mFlinger->getRenderColorB(); bool noEffect = renderEffect == 0; if (UNLIKELY(s.alpha < 0xFF) && noEffect) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else if (noEffect) { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (needsBlending()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } else { // Apply a render effect, which is simple color masks for now. GLenum env, src; env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; const GGLfixed alpha = (s.alpha << 16)/255; switch (renderEffect) { case RENDER_EFFECT_NIGHT: glColor4x(alpha, alpha*0.6204, alpha*0.3018, alpha); break; case RENDER_EFFECT_TERMINAL: glColor4x(0, alpha, 0, alpha); break; case RENDER_EFFECT_BLUE: glColor4x(0, 0, alpha, alpha); break; case RENDER_EFFECT_AMBER: glColor4x(alpha, alpha*0.75, 0, alpha); break; case RENDER_EFFECT_SALMON: glColor4x(alpha, alpha*0.5, alpha*0.5, alpha); break; case RENDER_EFFECT_FUSCIA: glColor4x(alpha, 0, alpha*0.5, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_N: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*renderColorB/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_R: glColor4x(alpha*(renderColorR-50)/1000, alpha*renderColorG/1000, alpha*(renderColorB-30)/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_C: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*(renderColorB+30)/1000, alpha); break; case RENDER_EFFECT_RED: glColor4x(alpha, 0, 0, alpha); break; } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } /* * compute texture coordinates * here, we handle NPOT, cropping and buffer transformations */ GLfloat cl, ct, cr, cb; if (!mBufferCrop.isEmpty()) { // source is cropped const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; cl = mBufferCrop.left * us; ct = mBufferCrop.top * vs; cr = mBufferCrop.right * us; cb = mBufferCrop.bottom * vs; } else { cl = 0; ct = 0; cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); } /* * For the buffer transformation, we apply the rotation last. * Since we're transforming the texture-coordinates, we need * to apply the inverse of the buffer transformation: * inverse( FLIP_V -> FLIP_H -> ROT_90 ) * <=> inverse( ROT_90 * FLIP_H * FLIP_V ) * = inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90) * = FLIP_V * FLIP_H * ROT_270 * <=> ROT_270 -> FLIP_H -> FLIP_V * * The rotation is performed first, in the texture coordinate space. * */ struct TexCoords { GLfloat u; GLfloat v; }; enum { // name of the corners in the texture map LB = 0, // left-bottom LT = 1, // left-top RT = 2, // right-top RB = 3 // right-bottom }; // vertices in screen space int vLT = LB; int vLB = LT; int vRB = RT; int vRT = RB; // the texture's source is rotated uint32_t transform = mBufferTransform; if (transform & HAL_TRANSFORM_ROT_90) { vLT = RB; vLB = LB; vRB = LT; vRT = RT; } if (transform & HAL_TRANSFORM_FLIP_V) { swap(vLT, vLB); swap(vRT, vRB); } if (transform & HAL_TRANSFORM_FLIP_H) { swap(vLT, vRT); swap(vLB, vRB); } TexCoords texCoords[4]; texCoords[vLT].u = cl; texCoords[vLT].v = ct; texCoords[vLB].u = cl; texCoords[vLB].v = cb; texCoords[vRB].u = cr; texCoords[vRB].v = cb; texCoords[vRT].u = cr; texCoords[vRT].v = ct; if (needsDithering()) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
bool Region::validate(const Region& reg, const char* name, bool silent) { bool result = true; const_iterator cur = reg.begin(); const_iterator const tail = reg.end(); const_iterator prev = cur; Rect b(*prev); while (cur != tail) { if (cur->isValid() == false) { ALOGE_IF(!silent, "%s: region contains an invalid Rect", name); result = false; } if (cur->right > region_operator<Rect>::max_value) { ALOGE_IF(!silent, "%s: rect->right > max_value", name); result = false; } if (cur->bottom > region_operator<Rect>::max_value) { ALOGE_IF(!silent, "%s: rect->right > max_value", name); result = false; } if (prev != cur) { b.left = b.left < cur->left ? b.left : cur->left; b.top = b.top < cur->top ? b.top : cur->top; b.right = b.right > cur->right ? b.right : cur->right; b.bottom = b.bottom > cur->bottom ? b.bottom : cur->bottom; if ((*prev < *cur) == false) { ALOGE_IF(!silent, "%s: region's Rects not sorted", name); result = false; } if (cur->top == prev->top) { if (cur->bottom != prev->bottom) { ALOGE_IF(!silent, "%s: invalid span %p", name, cur); result = false; } else if (cur->left < prev->right) { ALOGE_IF(!silent, "%s: spans overlap horizontally prev=%p, cur=%p", name, prev, cur); result = false; } } else if (cur->top < prev->bottom) { ALOGE_IF(!silent, "%s: spans overlap vertically prev=%p, cur=%p", name, prev, cur); result = false; } prev = cur; } cur++; } if (b != reg.getBounds()) { result = false; ALOGE_IF(!silent, "%s: invalid bounds [%d,%d,%d,%d] vs. [%d,%d,%d,%d]", name, b.left, b.top, b.right, b.bottom, reg.getBounds().left, reg.getBounds().top, reg.getBounds().right, reg.getBounds().bottom); } if (reg.mStorage.size() == 2) { result = false; ALOGE_IF(!silent, "%s: mStorage size is 2, which is never valid", name); } if (result == false && !silent) { reg.dump(name); CallStack stack(LOG_TAG); } return result; }