static BOOL recalc_invrgn_by_rect(control_t *p_ctrl, BOOL is_add, BOOL is_recalc_children, const rect_t *p_rc) { rect_t rc_invalid, rc_client; MT_ASSERT(p_ctrl != NULL); if(OBJ_ATTR_HIDDEN == p_ctrl->attr) { return FALSE; } ctrl_get_client_rect(p_ctrl, &rc_client); if(p_rc != NULL) { copy_rect(&rc_invalid, p_rc); update_invrgn_by_rect(&p_ctrl->invrgn_info, is_add, &rc_invalid, &rc_client); } else { copy_rect(&rc_invalid, &rc_client); update_invrgn_by_rect(&p_ctrl->invrgn_info, is_add, NULL, &rc_client); } if(is_recalc_children && p_ctrl->p_child != NULL) { recalc_children_invrgn(p_ctrl->p_child, is_add, &rc_invalid); } return TRUE; }
/* dx = in columns, dy = in lines */ void scroll_window(int dx, int dy) { Graphics *g; Rect r; Point p; /* a negative value scrolls up */ assert(lines != NULL); if (dy < 0) { assert(-dy < NUM_LINES); memmove(lines,lines-dy*NUM_COLUMNS,(NUM_LINES+dy)*NUM_COLUMNS*sizeof(TCHAR)); memset(lines+(NUM_LINES+dy)*NUM_COLUMNS*sizeof(TCHAR), __T(' '), -dy*NUM_COLUMNS); } else if (dy > 0) { assert(dy < NUM_LINES); memmove(lines+dy*NUM_COLUMNS,lines,(NUM_LINES-dy)*NUM_COLUMNS*sizeof(TCHAR)); memset(lines, __T(' '), dy*NUM_COLUMNS); } /* if */ csry += dy; if (csry < 0) csry = 0; if (csry >= NUM_LINES) csry=NUM_LINES - 1; assert(font != NULL); dx *= font_width(font, "x", 1); dy *= font_height(font); g = get_window_graphics(win); r = get_window_area(win); p = pt(r.x + dx, r.y + dy); copy_rect(g, p, g, r); if (dy > 0) { /* moving window contents downwards */ redraw_rect(win, rect(0,0,r.width,dy)); } else if (dy < 0) { /* moving window contents upwards */ redraw_rect(win, rect(0,r.height+dy,r.width,0-dy)); } /* if */ if (dx > 0) { /* moving window contents to the right */ redraw_rect(win, rect(0,0,dx,r.height)); } else if (dx < 0) { /* moving window contents to the left */ redraw_rect(win, rect(r.width+dx,0,0-dx,r.height)); } /* if */ del_graphics(g); }
int main(int argc, char**argv) { if(argc != 3) { dprintf(2, "%s in.png out.png\n", argv[0]); return 1; } const char *in = argv[1]; const char *out = argv[2]; struct Pix* pin = pixRead(in); struct Pix* pin32 = pixConvertTo32(pin); struct Pix* pout = pixCreate(59, 16*30, 32); int xo = 0, yo = 0, i; uint32_t *od = (void*) pout->data; for(i = 0; i < 30; i++) { int xi = 3 + (i % 5) * 64; int yi = 5 + (i / 5) * 23; copy_rect(xi, yi, 59, 16, (void*) pin32->data, pin32->w, od); od += 16*59; } pixWritePng(out, pout, 0); return 0; }
static bool process_server_message ( filter_t *p_filter, rfbServerToClientMsg *msg ) { filter_sys_t *p_sys = p_filter->p_sys; switch (msg->type) { case rfbFramebufferUpdate: { msg->fu.nRects = htons(msg->fu.nRects); rfbFramebufferUpdateRectHeader hdr; for (int i_rect = 0; i_rect < msg->fu.nRects; i_rect++) { if (!read_exact(p_filter, p_sys->i_socket, &hdr, sz_rfbFramebufferUpdateRectHeader ) ) { msg_Err( p_filter, "Could not read FrameBufferUpdate header" ); return false; } hdr.r.x = htons(hdr.r.x); hdr.r.y = htons(hdr.r.y); hdr.r.w = htons(hdr.r.w); hdr.r.h = htons(hdr.r.h); hdr.encoding = htonl(hdr.encoding); switch (hdr.encoding) { case rfbEncodingRaw: { int i_line; for (i_line = 0; i_line < hdr.r.h; i_line++) { if ( !read_exact( p_filter, p_sys->i_socket, p_sys->read_buffer, hdr.r.w ) ) { msg_Err( p_filter, "Could not read FrameBufferUpdate line data" ); return false; } vlc_mutex_lock( &p_sys->lock ); if ( !raw_line( p_sys, hdr.r.x, hdr.r.y + i_line, hdr.r.w ) ) { msg_Err( p_filter, "raw_line failed." ); vlc_mutex_unlock( &p_sys->lock ); return false; } vlc_mutex_unlock( &p_sys->lock ); } } break; case rfbEncodingCopyRect: { rfbCopyRect rect; if ( !read_exact( p_filter, p_sys->i_socket, &rect, sz_rfbCopyRect ) ) { msg_Err( p_filter, "Could not read rfbCopyRect" ); return false; } rect.srcX = htons( rect.srcX ); rect.srcY = htons( rect.srcY ); vlc_mutex_lock( &p_sys->lock ); if ( !copy_rect( p_sys, hdr.r.x, hdr.r.y, hdr.r.w, hdr.r.h, rect.srcX, rect.srcY ) ) { msg_Err( p_filter, "copy_rect failed." ); vlc_mutex_unlock( &p_sys->lock ); return false; } vlc_mutex_unlock( &p_sys->lock ); } break; case rfbEncodingRRE: { rfbRREHeader rrehdr; if ( !read_exact( p_filter, p_sys->i_socket, &rrehdr, sz_rfbRREHeader ) ) { msg_Err( p_filter, "Could not read rfbRREHeader" ); return false; } uint8_t i_pixcolor; if ( !read_exact( p_filter, p_sys->i_socket, &i_pixcolor, 1 ) ) { msg_Err( p_filter, "Could not read RRE pixcolor" ); return false; } vlc_mutex_lock( &p_sys->lock ); if ( !fill_rect( p_sys, hdr.r.x, hdr.r.y, hdr.r.w, hdr.r.h, i_pixcolor) ) { msg_Err( p_filter, "main fill_rect failed." ); vlc_mutex_unlock( &p_sys->lock ); return false; } vlc_mutex_unlock( &p_sys->lock ); rrehdr.nSubrects = htonl(rrehdr.nSubrects); int i_datasize = rrehdr.nSubrects * ( sizeof(i_pixcolor) + sz_rfbRectangle ) ; if ( i_datasize > READ_BUFFER_SIZE ) { msg_Err( p_filter, "Buffer too small, " "need %u bytes", i_datasize ); return false; } if ( !read_exact( p_filter, p_sys->i_socket, p_sys->read_buffer, i_datasize ) ) { msg_Err( p_filter, "Could not read RRE subrect data" ); return false; } uint32_t i_subrect; rfbRectangle* p_subrect; int i_offset = 0; vlc_mutex_lock( &p_sys->lock ); for ( i_subrect = 0; i_subrect < rrehdr.nSubrects; i_subrect++) { i_pixcolor = p_sys->read_buffer[i_offset]; i_offset += sizeof(i_pixcolor); p_subrect = (rfbRectangle*)(p_sys->read_buffer + i_offset); i_offset += sz_rfbRectangle; if (!fill_rect( p_sys, htons(p_subrect->x) + hdr.r.x, htons(p_subrect->y) + hdr.r.y, htons(p_subrect->w), htons(p_subrect->h), i_pixcolor) ) { msg_Err( p_filter, "subrect %u fill_rect failed.", i_subrect ); vlc_mutex_unlock( &p_sys->lock ); return false; } } vlc_mutex_unlock( &p_sys->lock ); } break; } } vlc_mutex_lock( &p_sys->lock ); p_sys->b_need_update = true; vlc_mutex_unlock( &p_sys->lock ); } return true; case rfbSetColourMapEntries: { msg->scme.nColours = htons(msg->scme.nColours); msg->scme.firstColour = htons(msg->scme.firstColour); int i_datasize; if ( p_sys->b_alpha_from_vnc ) { i_datasize = 2 * msg->scme.nColours * 4; } else { i_datasize = 2 * msg->scme.nColours * 3; } if ( i_datasize > READ_BUFFER_SIZE ) { msg_Err( p_filter, "Buffer too small, need %u bytes", i_datasize ); return false; } if ( !read_exact( p_filter, p_sys->i_socket, p_sys->read_buffer, i_datasize ) ) { msg_Err( p_filter, "Could not read color map data" ); return false; } uint8_t i_red, i_green, i_blue, i_alpha, i_color_index; uint16_t i_offset = 0; i_alpha = 255; for (int i = 0; i < msg->scme.nColours; i++) { i_color_index = i+msg->scme.firstColour; if ( p_sys->b_alpha_from_vnc ) { i_alpha = p_sys->read_buffer[i_offset]; i_offset += 2; } i_red = p_sys->read_buffer[i_offset]; i_offset += 2; i_green = p_sys->read_buffer[i_offset]; i_offset += 2; i_blue = p_sys->read_buffer[i_offset]; i_offset += 2; rgb_to_yuv( &p_sys->ar_color_table_yuv[i_color_index][0], &p_sys->ar_color_table_yuv[i_color_index][1], &p_sys->ar_color_table_yuv[i_color_index][2], i_red, i_green, i_blue ); p_sys->ar_color_table_yuv[i][3] = i_alpha; } } return true; case rfbBell: msg_Err( p_filter, "rfbBell received" ); return true; case rfbServerCutText: msg->sct.length = htons(msg->sct.length); if ( msg->sct.length > READ_BUFFER_SIZE ) { msg_Err( p_filter, "Buffer too small, need %u bytes", msg->sct.length ); return false; } if ( !read_exact( p_filter, p_sys->i_socket, p_sys->read_buffer, msg->sct.length ) ) { msg_Err( p_filter, "Could not read Reading rfbServerCutText data" ); return false; } return true; case rfbReSizeFrameBuffer: msg_Err( p_filter, "Reading rfbReSizeFrameBuffer not implemented" ); return false; default: msg_Err( p_filter, "Invalid message %u received", msg->type ); return false; } return false; }
void PSTextureEncoder::Encode(u8* dst, const EFBCopyParams& params, u32 native_width, u32 bytes_per_row, u32 num_blocks_y, u32 memory_stride, const EFBRectangle& src_rect, bool scale_by_half) { // Resolve MSAA targets before copying. // FIXME: Instead of resolving EFB, it would be better to pick out a // single sample from each pixel. The game may break if it isn't // expecting the blurred edges around multisampled shapes. ID3D11ShaderResourceView* pEFB = params.depth ? FramebufferManager::GetResolvedEFBDepthTexture()->GetSRV() : FramebufferManager::GetResolvedEFBColorTexture()->GetSRV(); // Reset API g_renderer->ResetAPIState(); // Set up all the state for EFB encoding { const u32 words_per_row = bytes_per_row / sizeof(u32); D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, FLOAT(words_per_row), FLOAT(num_blocks_y)); D3D::context->RSSetViewports(1, &vp); constexpr EFBRectangle fullSrcRect(0, 0, EFB_WIDTH, EFB_HEIGHT); TargetRectangle targetRect = g_renderer->ConvertEFBRectangle(fullSrcRect); D3D::context->OMSetRenderTargets( 1, &static_cast<DXTexture*>(m_encoding_render_texture.get())->GetRawTexIdentifier()->GetRTV(), nullptr); EFBEncodeParams encode_params; encode_params.SrcLeft = src_rect.left; encode_params.SrcTop = src_rect.top; encode_params.DestWidth = native_width; encode_params.ScaleFactor = scale_by_half ? 2 : 1; encode_params.y_scale = params.y_scale; D3D::context->UpdateSubresource(m_encode_params, 0, nullptr, &encode_params, 0, 0); D3D::stateman->SetPixelConstants(m_encode_params); // We also linear filtering for both box filtering and downsampling higher resolutions to 1x // TODO: This only produces perfect downsampling for 2x IR, other resolutions will need more // complex down filtering to average all pixels and produce the correct result. // Also, box filtering won't be correct for anything other than 1x IR if (scale_by_half || g_renderer->GetEFBScale() != 1 || params.y_scale > 1.0f) D3D::SetLinearCopySampler(); else D3D::SetPointCopySampler(); D3D::drawShadedTexQuad(pEFB, targetRect.AsRECT(), g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight(), GetEncodingPixelShader(params), VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); // Copy to staging buffer MathUtil::Rectangle<int> copy_rect(0, 0, words_per_row, num_blocks_y); m_encoding_readback_texture->CopyFromTexture(m_encoding_render_texture.get(), copy_rect, 0, 0, copy_rect); m_encoding_readback_texture->Flush(); if (m_encoding_readback_texture->Map()) { m_encoding_readback_texture->ReadTexels(copy_rect, dst, memory_stride); m_encoding_readback_texture->Unmap(); } } // Restore API FramebufferManager::BindEFBRenderTarget(); g_renderer->RestoreAPIState(); }