2009-04-30 40 views
7

Tôi đã tạo một điều khiển WPF (kế thừa từ FrameworkElement) hiển thị một đồ họa lát gạch có thể được quét. Mỗi ô là 256x256 pixel ở 24bpp. Tôi đã ghi đè OnRender. Ở đó, tôi tải bất kỳ lát mới (như BitmapFrame), sau đó vẽ tất cả các gạch có thể nhìn thấy bằng cách sử dụng drawingContext.DrawImage.WPF hiển thị hiệu suất với BitmapSource

Bây giờ, bất cứ khi nào có nhiều hơn một ô xếp mới cho mỗi chu kỳ hiển thị, tốc độ khung hình giảm từ 60 khung hình xuống 0 trong khoảng một giây. Điều này không phải do tải các hình ảnh (mất khoảng mili giây), cũng không phải bởi DrawImage (không mất thời gian chút nào vì nó chỉ lấp đầy một số cấu trúc dữ liệu hiển thị trung gian).

Tôi đoán là chính chuỗi hiển thị sẽ tự động kích hoạt bất cứ khi nào nó nhận được số lượng lớn (~ 20) của các phiên bản BitmapSource mới (tức là, những trường hợp chưa được lưu trong bộ nhớ cache). Hoặc là nó dành rất nhiều thời gian chuyển đổi chúng sang một số định dạng tương thích DirectX nội bộ hoặc nó có thể là một vấn đề bộ nhớ đệm. Nó không thể chạy hết RAM video; Perforator cho thấy các đỉnh ở dưới 60MB, tôi có 256MB. Ngoài ra, Perforator nói rằng tất cả các mục tiêu render đều được tăng tốc phần cứng, vì vậy cũng không thể.

Mọi thông tin chi tiết sẽ được đánh giá cao!

Cảm ơn trước

Daniel

@RandomEngy:
BitmapScalingMode.LowQuality giảm vấn đề một chút, nhưng không thoát khỏi nó. Tôi đã tải gạch ở độ phân giải dự định. Và nó không thể là trình điều khiển đồ họa, được cập nhật (Nvidia).
Tôi hơi ngạc nhiên khi biết rằng việc nhân rộng mất nhiều thời gian. Cách tôi hiểu nó, một bitmap (bất kể kích thước của nó) chỉ được nạp như một kết cấu Direct3D và sau đó được chia tỷ lệ phần cứng. Như một vấn đề của thực tế, một khi bitmap đã được trả lại cho lần đầu tiên, tôi có thể thay đổi luân phiên và quy mô của nó mà không có bất kỳ đóng băng thêm.

Trả lời

3

Nó không chỉ với một số lượng lớn hình ảnh. Chỉ cần một hình ảnh lớn là đủ để giữ lại hiển thị cho đến khi nó được tải vào và điều đó có thể khá đáng chú ý khi kích thước hình ảnh của bạn bắt đầu tăng lên trong hàng nghìn hình ảnh.

Tôi đồng ý với bạn rằng đó có thể là chuỗi kết xuất: Tôi đã thực hiện kiểm tra và chuỗi giao diện người dùng vẫn vui vẻ gửi thư trong khi quá trình hiển thị này diễn ra từ cố gắng hiển thị BitmapImage được lưu trước đầy đủ.

Nó phải thực hiện một số loại chuyển đổi hoặc chuẩn bị trên hình ảnh, giống như bạn đang suy đoán. Tôi đã cố gắng để giảm thiểu điều này trong ứng dụng của tôi bằng cách "rendering" nhưng ẩn hình ảnh, sau đó tiết lộ nó khi tôi cần phải hiển thị nó. Tuy nhiên điều này là ít hơn lý tưởng vì đóng băng rendering xảy ra anyway.

(Chỉnh sửa)

Một số followup: Sau khi thảo luận về bí danh MS WPF, tôi đã tìm thấy nguyên nhân gây ra sự chậm trễ. Trên máy Server 2008 của tôi, nó là sự kết hợp của các trình điều khiển video cũ không hỗ trợ mô hình trình điều khiển WDDM mới và sự chậm trễ để thay đổi kích thước hình ảnh.

Nếu kích thước hình ảnh nguồn khác với kích thước hiển thị, điều đó sẽ làm trễ chuỗi hiển thị trước khi hình ảnh hiển thị. Theo mặc định, hình ảnh được đặt ở chất lượng cao nhất, nhưng bạn có thể thay đổi tùy chọn chia tỷ lệ để hiển thị bằng cách gọi RenderOptions.SetBitmapScalingMode(uiImage, BitmapScalingMode.LowQuality);. Một khi tôi đã làm điều đó, sự đóng băng bí ẩn trước khi hiển thị một hình ảnh biến mất. Một thay thế, nếu bạn không thích giảm chất lượng trong mở rộng quy mô, là tải BitmapImage với DecodePixelWidth/Height bằng với kích thước nó sẽ được hiển thị tại. Sau đó, nếu bạn tải BitmapImage trên một chủ đề nền, bạn sẽ không có sự chậm trễ trong việc hiển thị nó.

0

Cũng thử các tính năng này;

/* ivis is declared in XAML <Image x:Name="iVis" UseLayoutRounding="True" SnapsToDevicePixels="True" /> */ 

iVis.Stretch = Stretch.None; 
RenderOptions.SetBitmapScalingMode(iVis, BitmapScalingMode.NearestNeighbor); 
RenderOptions.SetEdgeMode(iVis, EdgeMode.Aliased); 
VisualBitmapScalingMode = BitmapScalingMode.NearestNeighbor; 
iVis.Source = **** your bitmap source **** 

Tôi gặp sự cố với hiệu suất khi sử dụng lượng lớn màu "A" của kênh, chờ cho đến sau khi hình ảnh được hiển thị để mở rộng nó hoạt động tốt hơn cho tôi.

Ngoài ra, khi bạn nói bạn đang sử dụng đồ họa lát gạch?

Bạn thường sẽ sử dụng TileBrush để chỉ cần đặt làm Bàn chải trên FrameworkElement của mình. Nếu bạn đang làm động hoặc thêm động từ mới, bạn có thể tạo cọ vẽ, sau đó áp dụng chúng cho đối tượng khi bạn đi theo cách thủ công, hãy đảm bảo Freeze nếu bạn có thể. Ngoài ra, VisualBitmapScalingMode là một tài sản của bất kỳ Visual.

Các vấn đề liên quan