void Canvas::draw_surface_batch(const SurfacePtr& surface, std::vector<Rectf> srcrects, std::vector<Rectf> dstrects, std::vector<float> angles, const Color& color, int layer) { if (!surface) return; auto request = new(m_obst) TextureRequest(); request->type = TEXTURE; request->layer = layer; request->flip = m_context.transform().flip ^ surface->get_flip(); request->alpha = m_context.transform().alpha; request->color = color; request->srcrects = std::move(srcrects); request->dstrects = std::move(dstrects); request->angles = std::move(angles); for (auto& dstrect : request->dstrects) { dstrect = Rectf(apply_translate(dstrect.p1()), dstrect.get_size()); } request->texture = surface->get_texture().get(); request->displacement_texture = surface->get_displacement_texture().get(); m_requests.push_back(request); }
void DrawingContext::draw_surface(SurfacePtr surface, const Vector& position, float angle, const Color& color, const Blend& blend, int layer) { assert(surface != 0); DrawingRequest* request = new(obst) DrawingRequest(); request->target = target; request->type = SURFACE; request->pos = transform.apply(position); if(request->pos.x >= SCREEN_WIDTH || request->pos.y >= SCREEN_HEIGHT || request->pos.x + surface->get_width() < 0 || request->pos.y + surface->get_height() < 0) return; request->layer = layer; request->drawing_effect = transform.drawing_effect; request->alpha = transform.alpha; request->angle = angle; request->color = color; request->blend = blend; SurfaceRequest* surfacerequest = new(obst) SurfaceRequest(); surfacerequest->surface = surface.get(); request->request_data = surfacerequest; requests->push_back(request); }
// Retarget the current texture to the specified surface buffer. EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { EGL_API_ENTRY("%p, %p, %d", dpy, surface, buffer); EglDisplayImpl* display = EglDisplayImpl::GetDisplay(dpy); if (display == NULL || display->IsInitialized() == false) { SetError(EGL_BAD_DISPLAY); return EGL_FALSE; } SurfacePtr s = display->GetSurfaces().Get(surface); if (s == NULL) { SetError(EGL_BAD_SURFACE); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { SetError(EGL_BAD_PARAMETER); return EGL_FALSE; } if (s->GetTextureFormat() == EGL_NO_TEXTURE) { SetError(EGL_BAD_MATCH); return EGL_FALSE; } if (!(s->GetSurfaceType() & EGL_PBUFFER_BIT)) { SetError(EGL_BAD_SURFACE); return EGL_FALSE; } s->BindTexImage(); return EGL_TRUE; }
EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) { if (!EglValidate::surfaceTarget(readdraw)) { return EGL_NO_SURFACE; } ThreadInfo* thread = getThreadInfo(); EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay); ContextPtr ctx = thread->eglContext; if(dpy && ctx.Ptr()) { SurfacePtr surface = readdraw == EGL_READ ? ctx->read() : ctx->draw(); if(surface.Ptr()) { // This double check is required because a surface might still be // current after it is destroyed - in which case its handle should // be invalid, that is EGL_NO_SURFACE should be returned even // though the surface is current. EGLSurface s = (EGLSurface)SafePointerFromUInt(surface->getHndl()); surface = dpy->getSurface(s); if(surface.Ptr()) { return s; } } } return EGL_NO_SURFACE; }
void draw_particles() { glPushMatrix(); glMultMatrixf(get_modelview().matrix); OpenGLState state; state.bind_texture(surface->get_texture()); state.set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); state.enable(GL_BLEND); state.activate(); glBegin(GL_QUADS); for(ParticleSystem::Particles::iterator i = psys.begin(); i != psys.end(); ++i) { if (i->t != -1.0f) { float p = 1.0f - psys.get_progress(i->t); Color color(psys.get_color_start().r * p + psys.get_color_stop().r * (1.0f - p), psys.get_color_start().g * p + psys.get_color_stop().g * (1.0f - p), psys.get_color_start().b * p + psys.get_color_stop().b * (1.0f - p), psys.get_color_start().a * p + psys.get_color_stop().a * (1.0f - p)); // scale float scale = psys.get_size_start() + psys.get_progress(i->t) * (psys.get_size_stop() - psys.get_size_start()); float width = surface->get_width() * scale; float height = surface->get_height() * scale; // rotate float x_rot = width/2; float y_rot = height/2; if (i->angle != 0) { float s = sinf(math::pi * i->angle/180.0f); float c = cosf(math::pi * i->angle/180.0f); x_rot = (width/2) * c - (height/2) * s; y_rot = (width/2) * s + (height/2) * c; } glColor4f(color.r, color.g, color.b, color.a); glTexCoord2f(0, 0); glVertex2f(i->x - x_rot, i->y - y_rot); glTexCoord2f(1, 0); glVertex2f(i->x + y_rot, i->y - x_rot); glTexCoord2f(1, 1); glVertex2f(i->x + x_rot, i->y + y_rot); glTexCoord2f(0, 1); glVertex2f(i->x - y_rot, i->y + x_rot); } } glEnd(); glPopMatrix(); }
EGLint EglDisplayImpl::SwapBuffers(EGLSurface egl_surface) { SurfacePtr sfc = surfaces_.Get(egl_surface); if (sfc == NULL) { return EGL_BAD_SURFACE; } else if (sfc->SwapBuffers()) { return EGL_SUCCESS; } else { return EGL_CONTEXT_LOST; } }
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface surface) { VALIDATE_DISPLAY(display); SurfacePtr srfc = dpy->getSurface(surface); if(!srfc.Ptr()) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } dpy->removeSurface(surface); return EGL_TRUE; }
// Set the timestamp for the specified surface. void eglBeginFrame(EGLDisplay dpy, EGLSurface surface) { EGL_API_ENTRY("%p, %p", dpy, surface); EglDisplayImpl* display = EglDisplayImpl::GetDisplay(dpy); if (display == NULL || display->IsInitialized() == false) { SetError(EGL_BAD_DISPLAY); return; } SurfacePtr s = display->GetSurfaces().Get(surface); if (s == NULL) { SetError(EGL_BAD_SURFACE); return; } const int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC); s->SetTimestamp(timestamp); }
void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { int i; int16 mouseX; int16 mouseY; MouseButtons buttons; SurfacePtr surface; SoundDesc samples[4]; int16 comp[5] = { 0, 1, 2, 3, -1 }; static const char *const sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; surface = _vm->_video->initSurfDesc(320, 200); _vm->_video->drawPackedSprite("2ille.ims", *surface); _vm->_draw->_frontSurface->blit(*surface, 0, 0, 319, 199, 0, 0); _vm->_video->drawPackedSprite("2ille4.ims", *surface); _vm->_draw->_frontSurface->blit(*surface, 0, 0, 319, 199, 320, 0); _vm->_util->setScrollOffset(320, 0); _vm->_video->dirtyRectsAll(); _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); _vm->_util->longDelay(1000); for (i = 320; i >= 0; i--) { _vm->_util->setScrollOffset(i, 0); _vm->_video->dirtyRectsAll(); if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == kKeyEscape) || _vm->shouldQuit()) { _vm->_palAnim->fade(0, -2, 0); _vm->_draw->_frontSurface->clear(); memset((char *)_vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); WRITE_VAR(0, kKeyEscape); WRITE_VAR(57, (uint32) -1); break; } } if (!_vm->shouldQuit()) { _vm->_util->setScrollOffset(0, 0); _vm->_video->dirtyRectsAll(); } surface.reset(); if (VAR(57) == ((uint32) -1)) return; for (i = 0; i < 4; i++) _vm->_sound->sampleLoad(&samples[i], SOUND_SND, sndFiles[i]); _vm->_sound->blasterPlayComposition(comp, 0, samples, 4); _vm->_sound->blasterWaitEndPlay(true, false); _vm->_palAnim->fade(0, 0, 0); _vm->_draw->_frontSurface->clear(); }
void TtFontAsset::RenderText( SurfacePtr dest, int& x, int& y, const char* text, const pei::Color& color /*= pei::XColor(255,255,255)*/ ) { // assert ( pFont ); if (!m_TtFont || dest.get() == NULL ) { return; } #ifdef _HAS_SDL_TTF_ SDL_Surface *text_surface = NULL; // this is a hack! We swap r & g and correct the color format manually // SDL_ttf renders ARGB, but we need ABGR (or LE RGBA) to match RGBA texture format - performace reasons! SDL_Color c = { color.b, color.g, color.r, color.a }; if ( (text_surface = TTF_RenderText_Blended( (TTF_Font*)m_TtFont->GetFontHandle(), text, c )) != NULL ) { // swap r&g in the format description text_surface->format->Rmask = 0x000000ff; text_surface->format->Rshift = 0; text_surface->format->Bmask = 0x00ff0000; text_surface->format->Bshift = 16; pei::SurfacePtr txt( new pei::SDL::SurfaceWrapper(text_surface)); pei::Blitter blitter(pei::PixOpPtr(new PixOpAlphaBlitSrcAlpha(txt->GetFormat(),dest->GetFormat()) ) ); blitter.Blit( txt, dest, x, y, txt->GetWidth(), txt->GetHeight(), 0, 0 ); int tw, th; TTF_SizeText( (TTF_Font*)m_TtFont->GetFontHandle(), text, &tw, &th); Uint32 font_height = TTF_FontHeight((TTF_Font*)m_TtFont->GetFontHandle()); // - a - 2*d; y += font_height; x += tw; } #endif }
EGLBoolean eglPresentationTimeANDROID(EGLDisplay dpy, EGLSurface surface, EGLnsecsANDROID time) { EGL_API_ENTRY("%p, %p, %lld", dpy, surface, time); EglDisplayImpl* display = EglDisplayImpl::GetDisplay(dpy); if (display == NULL || display->IsInitialized() == false) { SetError(EGL_BAD_DISPLAY); return EGL_FALSE; } SurfacePtr s = display->GetSurfaces().Get(surface); if (s == NULL) { SetError(EGL_BAD_SURFACE); return EGL_FALSE; } s->SetTimestamp(time); return EGL_TRUE; }
void DrawingContext::draw_surface_part(SurfacePtr surface, const Rectf& srcrect, const Rectf& dstrect, int layer) { assert(surface != 0); DrawingRequest* request = new(obst) DrawingRequest(); request->target = target; request->type = SURFACE_PART; request->pos = transform.apply(dstrect.p1); request->layer = layer; request->drawing_effect = transform.drawing_effect; request->alpha = transform.alpha; SurfacePartRequest* surfacepartrequest = new(obst) SurfacePartRequest(); surfacepartrequest->srcrect = srcrect; surfacepartrequest->dstsize = dstrect.get_size(); surfacepartrequest->surface = surface.get(); request->request_data = surfacepartrequest; requests->push_back(request); }
// Get the surface associated with the current rendering context. EGLSurface eglGetCurrentSurface(EGLint readdraw) { EGL_API_ENTRY("0x%x", readdraw); if (readdraw != EGL_READ && readdraw != EGL_DRAW) { SetError(EGL_BAD_PARAMETER); return EGL_NO_SURFACE; } ContextPtr context = GetContext(); if (context == NULL) { return EGL_NO_SURFACE; } SurfacePtr surface = context->GetSurface(); if (surface == NULL) { return EGL_NO_SURFACE; } return surface->GetKey(); }
void Canvas::draw_surface_scaled(const SurfacePtr& surface, const Rectf& dstrect, int layer, const PaintStyle& style) { draw_surface_part(surface, Rectf(0.0f, 0.0f, static_cast<float>(surface->get_width()), static_cast<float>(surface->get_height())), dstrect, layer, style); }
ImagePtr VaapiImage::derive(const SurfacePtr& surface) { ImagePtr image; if (!surface) return image; DisplayPtr display = surface->getDisplay(); VAImagePtr vaImage(new VAImage); VAStatus status = vaDeriveImage(display->getID(), surface->getID(), vaImage.get()); if (!checkVaapiStatus(status, "vaDeriveImage()")) { return image; } image.reset(new VaapiImage(display, surface, vaImage)); return image; }
void Canvas::draw_surface(const SurfacePtr& surface, const Vector& position, float angle, const Color& color, const Blend& blend, int layer) { if (!surface) return; const auto& cliprect = m_context.get_cliprect(); // discard clipped surface if (position.x > cliprect.get_right() || position.y > cliprect.get_bottom() || position.x + static_cast<float>(surface->get_width()) < cliprect.get_left() || position.y + static_cast<float>(surface->get_height()) < cliprect.get_top()) return; auto request = new(m_obst) TextureRequest(); request->type = TEXTURE; request->layer = layer; request->flip = m_context.transform().flip ^ surface->get_flip(); request->alpha = m_context.transform().alpha; request->blend = blend; request->srcrects.emplace_back(Rectf(surface->get_region())); request->dstrects.emplace_back(Rectf(apply_translate(position), Size(surface->get_width(), surface->get_height()))); request->angles.emplace_back(angle); request->texture = surface->get_texture().get(); request->displacement_texture = surface->get_displacement_texture().get(); request->color = color; m_requests.push_back(request); }
void Inter_v7::o7_loadImage() { Common::String file = _vm->_game->_script->evalString(); if (!file.contains('.')) file += ".TGA"; int16 spriteIndex = _vm->_game->_script->readValExpr(); int16 left = _vm->_game->_script->readValExpr(); int16 top = _vm->_game->_script->readValExpr(); int16 width = _vm->_game->_script->readValExpr(); int16 height = _vm->_game->_script->readValExpr(); int16 x = _vm->_game->_script->readValExpr(); int16 y = _vm->_game->_script->readValExpr(); int16 transp = _vm->_game->_script->readValExpr(); if (spriteIndex > 100) spriteIndex -= 80; if ((spriteIndex < 0) || (spriteIndex >= Draw::kSpriteCount)) { warning("o7_loadImage(): Sprite %d out of range", spriteIndex); return; } SurfacePtr destSprite = _vm->_draw->_spritesArray[spriteIndex]; if (!destSprite) { warning("o7_loadImage(): Sprite %d does not exist", spriteIndex); return; } Common::SeekableReadStream *imageFile = _vm->_dataIO->getFile(file); if (!imageFile) { warning("o7_loadImage(): No such file \"%s\"", file.c_str()); return; } SurfacePtr image = _vm->_video->initSurfDesc(1, 1); if (!image->loadImage(*imageFile)) { warning("o7_loadImage(): Failed to load image \"%s\"", file.c_str()); return; } int16 right = left + width - 1; int16 bottom = top + height - 1; destSprite->blit(*image, left, top, right, bottom, x, y, transp); }
bool VaapiDecoderVP8::allocNewPicture() { m_currentPicture = createPicture(m_currentPTS); if (!m_currentPicture) return false; SurfacePtr surface = m_currentPicture->getSurface(); ASSERT(m_frameWidth && m_frameHeight); if (!surface->resize(m_frameWidth, m_frameHeight)) { ASSERT(0 && "frame size is bigger than internal surface resolution"); return false; } DEBUG ("alloc new picture: %p with surface ID: %x", m_currentPicture.get(), m_currentPicture->getSurfaceID()); return true; }
EGLSurface EglDisplay::addSurface(SurfacePtr s ) { android::Mutex::Autolock mutex(m_lock); unsigned int hndl = s.Ptr()->getHndl(); EGLSurface ret =reinterpret_cast<EGLSurface> (hndl); if(m_surfaces.find(hndl) != m_surfaces.end()) { return ret; } m_surfaces[hndl] = s; return ret; }
SurfacePtr TempSpriteHandler::createSprite(int16 dataVar, int32 size, int32 offset) { SurfacePtr sprt; // Sprite requested? if (!isSprite(size)) return sprt; // Index sane? int index = getIndex(size); if ((index < 0) || (index >= Draw::kSpriteCount)) return sprt; // Sprite exists? if (!(sprt = _vm->_draw->_spritesArray[index])) return sprt; if (!create(sprt->getWidth(), sprt->getHeight(), sprt->getBPP() > 1)) sprt.reset(); return sprt; }
SurfacePtr Video::initSurfDesc(int16 width, int16 height, int16 flags) { SurfacePtr descPtr; if (flags & PRIMARY_SURFACE) assert((width == _surfWidth) && (height == _surfHeight)); if (flags & PRIMARY_SURFACE) { _vm->_global->_primaryWidth = width; _vm->_global->_primaryHeight = height; descPtr = _vm->_global->_primarySurfDesc; descPtr->resize(width, height); } else { assert(!(flags & DISABLE_SPR_ALLOC)); if (!(flags & SCUMMVM_CURSOR)) width = (width + 7) & 0xFFF8; descPtr = SurfacePtr(new Surface(width, height, _vm->getPixelFormat().bytesPerPixel)); } return descPtr; }
SurfacePtr VaapiSurface::create(const DisplayPtr& display, VaapiChromaType chromaType, uint32_t width, uint32_t height, void *surfAttribArray, uint32_t surfAttribNum) { VAStatus status; uint32_t format, i; VASurfaceAttrib *surfAttribs = (VASurfaceAttrib *) surfAttribArray; SurfacePtr surface; VASurfaceID id; assert((surfAttribs && surfAttribNum) || (!surfAttribs && !surfAttribNum)); format = vaapiChromaToVaChroma(chromaType); uint32_t externalBufHandle = 0; status = vaCreateSurfaces(display->getID(), format, width, height, &id, 1, surfAttribs, surfAttribNum); if (!checkVaapiStatus(status, "vaCreateSurfacesWithAttribute()")) return surface; for (int i = 0; i < surfAttribNum; i++) { if (surfAttribs[i].type == VASurfaceAttribExternalBufferDescriptor) { VASurfaceAttribExternalBuffers *surfAttribExtBuf = (VASurfaceAttribExternalBuffers *) surfAttribs[i].value. value.p; externalBufHandle = surfAttribExtBuf->buffers[0]; break; } } surface.reset(new VaapiSurface(display, id, chromaType, width, height,externalBufHandle)); return surface; }
bool VaapiDecSurfacePool::output(const SurfacePtr& surface, int64_t timeStamp) { VASurfaceID id = surface->getID(); AutoLock lock(m_lock); const Allocated::iterator it = m_allocated.find(id); if (it == m_allocated.end()) return false; assert(it->second == SURFACE_DECODING); it->second |= SURFACE_TO_RENDER; VideoRenderBuffer* buffer = m_renderMap[id];; m_output.push_back(buffer); return true; }
void Canvas::draw_surface_part(const SurfacePtr& surface, const Rectf& srcrect, const Rectf& dstrect, int layer, const PaintStyle& style) { if (!surface) return; auto request = new(m_obst) TextureRequest(); request->type = TEXTURE; request->layer = layer; request->flip = m_context.transform().flip ^ surface->get_flip(); request->alpha = m_context.transform().alpha * style.get_alpha(); request->blend = style.get_blend(); request->srcrects.emplace_back(srcrect); request->dstrects.emplace_back(apply_translate(dstrect.p1()), dstrect.get_size()); request->angles.emplace_back(0.0f); request->texture = surface->get_texture().get(); request->displacement_texture = surface->get_displacement_texture().get(); request->color = style.get_color(); m_requests.push_back(request); }
SurfacePtr VaapiEncoderBase::createSurface(VideoEncRawBuffer* inBuffer) { SurfacePtr surface = createSurface(); if (!surface) return surface; VaapiImage* image = surface->getDerivedImage(); if (!image) { ERROR("surface->getDerivedImage() failed"); surface.reset(); return surface; } VaapiImageRaw* raw = image->map(); if (!raw) { ERROR("image->map() failed"); surface.reset(); return surface; } assert(inBuffer->size == raw->width * raw->height * 3 / 2); uint8_t* src = inBuffer->data; uint8_t* dest = raw->pixels[0]; for (int i = 0; i < raw->height; i++) { memcpy(dest, src, raw->width); dest += raw->strides[0]; src += raw->width; } dest = raw->pixels[1]; for (int i = 0; i < raw->height/2; i++) { memcpy(dest, src, raw->width); dest += raw->strides[1]; src += raw->width; } return surface; }
SurfacePtr VaapiDecSurfacePool::acquireWithWait() { SurfacePtr surface; AutoLock lock(m_lock); if (m_flushing) { ERROR("uppper layer bug, only support flush in decode thread"); return surface; } while (m_freed.empty()) m_cond.wait(); if (m_flushing) { ERROR("uppper layer bug, only support flush in decode thread"); return surface; } assert(!m_freed.empty()); VASurfaceID id = m_freed.front(); m_freed.pop_front(); m_allocated[id] = SURFACE_DECODING; VaapiSurface* s = m_surfaceMap[id]; surface.reset(s, SurfaceRecycler(shared_from_this())); return surface; }
bool EglDisplay::removeSurface(SurfacePtr s) { android::Mutex::Autolock mutex(m_lock); SurfacesHndlMap::iterator it; for(it = m_surfaces.begin(); it!= m_surfaces.end(); it++) { if((*it).second.Ptr() == s.Ptr()) { break; } } if(it != m_surfaces.end()) { m_surfaces.erase(it); return true; } return false; }
/* Fills in VA picture parameter buffer */ bool VaapiEncoderH264::fill(VAEncPictureParameterBufferH264* picParam, const PicturePtr& picture, const SurfacePtr& surface) const { uint32_t i = 0; /* reference list, */ picParam->CurrPic.picture_id = surface->getID(); picParam->CurrPic.TopFieldOrderCnt = picture->m_poc; if (picture->m_type != VAAPI_PICTURE_TYPE_I) { for (i = 0; i < m_refList.size(); i++) { picParam->ReferenceFrames[i].picture_id = m_refList[i]->m_pic->getID(); picParam->ReferenceFrames[i].TopFieldOrderCnt = m_refList[i]->m_poc; picParam->ReferenceFrames[i].flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; } } for (; i < 16; ++i) { picParam->ReferenceFrames[i].picture_id = VA_INVALID_ID; } picParam->coded_buf = picture->m_codedBuffer->getID(); picParam->pic_parameter_set_id = 0; picParam->seq_parameter_set_id = 0; picParam->last_picture = 0; /* means last encoding picture */ picParam->frame_num = picture->m_frameNum; picParam->pic_init_qp = initQP(); picParam->num_ref_idx_l0_active_minus1 = (m_maxRefList0Count ? (m_maxRefList0Count - 1) : 0); picParam->num_ref_idx_l1_active_minus1 = (m_maxRefList1Count ? (m_maxRefList1Count - 1) : 0); picParam->chroma_qp_index_offset = 0; picParam->second_chroma_qp_index_offset = 0; /* set picture fields */ picParam->pic_fields.bits.idr_pic_flag = picture->isIdr(); picParam->pic_fields.bits.reference_pic_flag = (picture->m_type != VAAPI_PICTURE_TYPE_B); picParam->pic_fields.bits.entropy_coding_mode_flag = m_useCabac; picParam->pic_fields.bits.transform_8x8_mode_flag = m_useDct8x8; /* enable debloking */ picParam->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; return TRUE; }
// Helper function to add a polynomial trimcurve to an OSG::Surface NodeCore void addTrimCurve(SurfacePtr surf, const int numcps, const float xy[][2], const int dim, const int numknots, const float *knots, bool startnewloop = false) { std::vector<Real64> knotv; std::vector<Pnt2f> cps; int i; for (i = 0; i < numcps; ++i) { cps.push_back(Pnt2f(xy[i][0], xy[i][1])); } for (i = 0; i < numknots; ++i) { knotv.push_back(knots[i]); } beginEditCP(surf, Surface::CurveFieldMask); surf->addCurve(dim, knotv, cps, startnewloop); endEditCP (surf, Surface::CurveFieldMask); }
int32_t search(const Rect& rect, const int32_t count, Point* out_points) const { auto found_count = 0; auto iterator = top->get_iterator(rect); auto rank_buffer = (int32_t*)alloca(sizeof(int32_t)*count); for (auto p = iterator->iterate(); p != END_OF_DATA; p = iterator->iterate()) { *(rank_buffer + found_count) = p; if (++found_count == count) break; } for (auto i = 0; i < found_count; ++i) *(out_points + i) = ordered_points[rank_buffer[i]]; return found_count; }