static void do_draw_pix( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLint pitch, const void *pixels, GLuint dest ) { intelContextPtr intel = INTEL_CONTEXT(ctx); __DRIdrawablePrivate *dPriv = intel->driDrawable; drm_clip_rect_t *box = dPriv->pClipRects; int nbox = dPriv->numClipRects; int i; int src_offset = intelAgpOffsetFromVirtual( intel, pixels); int src_pitch = pitch; assert(src_offset != ~0); /* should be caught earlier */ if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); if (ctx->DrawBuffer) { y -= height; /* cope with pixel zoom */ if (!clip_pixelrect(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); return; } y = dPriv->h - y - height; /* convert from gl to hardware coords */ x += dPriv->x; y += dPriv->y; for (i = 0 ; i < nbox ; i++ ) { GLint bx, by, bw, bh; if (intersect_region(box + i, x, y, width, height, &bx, &by, &bw, &bh)) { intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, intel->intelScreen->front.pitch, intel->drawRegion->offset, bx - x, by - y, bx, by, bw, bh ); } } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); }
void TidyLines::tidy(std::vector<Line>& lines, const QtRegion& region) { m_region = region; double maxdim = std::max(m_region.width(),m_region.height()); // simple first pass -- remove very short lines lines.erase( std::remove_if(lines.begin(), lines.end(), [maxdim](const Line& line) {return line.length() < maxdim * TOLERANCE_B;}), lines.end()); // now load up m_lines... initLines(lines.size(),m_region.bottom_left,m_region.top_right); for (auto& line: lines) { addLine(line); } sortPixelLines(); std::vector<int> removelist; for (size_t i = 0; i < lines.size(); i++) { // n.b., as m_lines have just been made, note that what's in m_lines matches whats in lines // we will use this later! m_test++; m_lines[i].test = m_test; PixelRefVector list = pixelateLine( m_lines[i].line ); for (size_t a = 0; a < list.size(); a++) { auto pixel_lines = m_pixel_lines(static_cast<size_t>(list[a].y), static_cast<size_t>(list[a].x)); for (int j: pixel_lines) { if (m_lines[j].test != m_test && j > (int)i && intersect_region(lines[i],lines[j],TOLERANCE_B * maxdim)) { m_lines[j].test = m_test; int axis_i = (lines[i].width() >= lines[i].height()) ? XAXIS : YAXIS; int axis_j = (lines[j].width() >= lines[j].height()) ? XAXIS : YAXIS; int axis_reverse = (axis_i == XAXIS) ? YAXIS : XAXIS; if (axis_i == axis_j && fabs(lines[i].grad(axis_reverse) - lines[j].grad(axis_reverse)) < TOLERANCE_A && fabs(lines[i].constant(axis_reverse) - lines[j].constant(axis_reverse)) < (TOLERANCE_B * maxdim)) { // check for overlap and merge int parity = (axis_i == XAXIS) ? 1 : lines[i].sign(); if ((lines[i].start()[axis_i] * parity + TOLERANCE_B * maxdim) > (lines[j].start()[axis_j] * parity) && (lines[i].start()[axis_i] * parity) < (lines[j].end()[axis_j] * parity + TOLERANCE_B * maxdim)) { int end = ((lines[i].end()[axis_i] * parity) > (lines[j].end()[axis_j] * parity)) ? i : j; lines[j].bx() = lines[end].bx(); lines[j].by() = lines[end].by(); removelist.push_back(i); continue; // <- don't do this any more, we've zapped it and replaced it with the later line } if ((lines[j].start()[axis_j] * parity + TOLERANCE_B * maxdim) > (lines[i].start()[axis_i] * parity) && (lines[j].start()[axis_j] * parity) < (lines[i].end()[axis_i] * parity + TOLERANCE_B * maxdim)) { int end = ((lines[i].end()[axis_i] * parity) > (lines[j].end()[axis_j] * parity)) ? i : j; lines[j].ax() = lines[i].ax(); lines[j].ay() = lines[i].ay(); lines[j].bx() = lines[end].bx(); lines[j].by() = lines[end].by(); removelist.push_back(i); continue; // <- don't do this any more, we've zapped it and replaced it with the later line } } } } } } // comes out sorted, remove duplicates just in case removelist.erase(std::unique(removelist.begin(), removelist.end()), removelist.end()); for(auto iter = removelist.rbegin(); iter != removelist.rend(); ++iter) lines.erase(lines.begin() + *iter); removelist.clear(); // always clear this list, it's reused }
static GLboolean intelTryReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *pack, GLvoid *pixels ) { intelContextPtr intel = INTEL_CONTEXT(ctx); GLint size = 0; /* not really used */ GLint pitch = pack->RowLength ? pack->RowLength : width; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s\n", __FUNCTION__); /* Only accelerate reading to agp buffers. */ if ( !intelIsAgpMemory(intel, pixels, pitch * height * intel->intelScreen->cpp ) ) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: dest not agp\n", __FUNCTION__); return GL_FALSE; } /* Need GL_PACK_INVERT_MESA to cope with upsidedown results from * blitter: */ if (!pack->Invert) { if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__); return GL_FALSE; } if (!check_color(ctx, type, format, pack, pixels, size, pitch)) return GL_FALSE; switch ( intel->intelScreen->cpp ) { case 4: break; default: return GL_FALSE; } /* Although the blits go on the command buffer, need to do this and * fire with lock held to guarentee cliprects and drawing offset are * correct. * * This is an unusual situation however, as the code which flushes * a full command buffer expects to be called unlocked. As a * workaround, immediately flush the buffer on aquiring the lock. */ intelFlush( &intel->ctx ); LOCK_HARDWARE( intel ); { __DRIdrawablePrivate *dPriv = intel->driDrawable; int nbox = dPriv->numClipRects; int src_offset = intel->readRegion->offset; int src_pitch = intel->intelScreen->front.pitch; int dst_offset = intelAgpOffsetFromVirtual( intel, pixels); drm_clip_rect_t *box = dPriv->pClipRects; int i; assert(dst_offset != ~0); /* should have been caught above */ if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height)) { UNLOCK_HARDWARE( intel ); if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "%s totally clipped -- nothing to do\n", __FUNCTION__); return GL_TRUE; } /* convert to screen coords (y=0=top) */ y = dPriv->h - y - height; x += dPriv->x; y += dPriv->y; if (INTEL_DEBUG & DEBUG_PIXEL) fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n", src_pitch, pitch); /* We don't really have to do window clipping for readpixels. * The OpenGL spec says that pixels read from outside the * visible window region (pixel ownership) have undefined value. */ for (i = 0 ; i < nbox ; i++) { GLint bx, by, bw, bh; if (intersect_region(box+i, x, y, width, height, &bx, &by, &bw, &bh)) { intelEmitCopyBlitLocked( intel, intel->intelScreen->cpp, src_pitch, src_offset, pitch, dst_offset, bx, by, bx - x, by - y, bw, bh ); } } } UNLOCK_HARDWARE( intel ); intelFinish( &intel->ctx ); return GL_TRUE; }