void Layer::Draw() { UpdateLayerCanvas(); ui::TextureDrawParams texture_draw_params; for(Layer* layer=this; layer; layer=layer->parent_) { texture_draw_params.transform.ConcatTransform(layer->transform_); texture_draw_params.transform.ConcatTranslate( static_cast<float>(layer->bounds_.x()), static_cast<float>(layer->bounds_.y())); } // Only blend for transparent child layers. // The root layer will clobber the cleared bg. texture_draw_params.blend = parent_!=NULL && !fills_bounds_opaquely_; texture_draw_params.compositor_size = compositor_->size(); hole_rect_ = hole_rect_.Intersect( gfx::Rect(0, 0, bounds_.width(), bounds_.height())); if(hole_rect_.IsEmpty()) { DrawRegion(texture_draw_params, gfx::Rect(0, 0, bounds_.width(), bounds_.height())); } else { // Top (above the hole). DrawRegion(texture_draw_params, gfx::Rect( 0, 0, bounds_.width(), hole_rect_.y())); // Left (of the hole). DrawRegion(texture_draw_params, gfx::Rect( 0, hole_rect_.y(), hole_rect_.x(), hole_rect_.height())); // Right (of the hole). DrawRegion(texture_draw_params, gfx::Rect( hole_rect_.right(), hole_rect_.y(), bounds_.width() - hole_rect_.right(), hole_rect_.height())); // Bottom (below the hole). DrawRegion(texture_draw_params, gfx::Rect( 0, hole_rect_.bottom(), bounds_.width(), bounds_.height() - hole_rect_.bottom())); } }
// Draw a region of the screen. This attempts to minimise the drawing by eliminating items // that are completely obscured by items above them. We have to take into account the // transparency of items since items higher up the stack may be semi-transparent. void MHEngine::DrawRegion(QRegion toDraw, int nStackPos) { if (toDraw.isEmpty()) { return; // Nothing left to draw. } while (nStackPos >= 0) { MHVisible *pItem = CurrentApp()->m_DisplayStack.GetAt(nStackPos); // Work out how much of the area we want to draw is included in this visible. // The visible area will be empty if the item is transparent or not active. QRegion drawArea = pItem->GetVisibleArea() & toDraw; if (! drawArea.isEmpty()) // It contributes something. { // Remove the opaque area of this item from the region we have left. // If this item is (semi-)transparent this will not remove anything. QRegion newDraw = toDraw - pItem->GetOpaqueArea(); DrawRegion(newDraw, nStackPos - 1); // Do the items further down if any. // Now we've drawn anything below this we can draw this item on top. pItem->Display(this); return; } nStackPos--; } // We've drawn all the visibles and there's still some undrawn area. // Fill it with black. m_Context->DrawBackground(toDraw); }
VOID InvalidateCell(PGUI_CONSOLE_DATA GuiData, SHORT x, SHORT y) { SMALL_RECT CellRect = { x, y, x, y }; DrawRegion(GuiData, &CellRect); }
// Redraw an area of the display. This will be called via the context from Redraw. void MHEngine::DrawDisplay(QRegion toDraw) { if (m_fBooting) { return; } int nTopStack = CurrentApp() == NULL ? -1 : CurrentApp()->m_DisplayStack.Size() - 1; DrawRegion(toDraw, nTopStack); }
static VOID NTAPI GuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region) { PGUI_CONSOLE_DATA GuiData = This->Context; /* Do nothing if the window is hidden */ if (!GuiData->IsWindowVisible) return; DrawRegion(GuiData, Region); }
void ecMemoryLayoutWindow::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this); PrepareDC(dc); ecConfigToolDoc* pDoc = wxGetApp().GetConfigToolDoc(); if (pDoc == NULL) // no document so nothing to draw return; #if 0 // clear the lists of region and section rectangles used for hit testing listRegionRect.RemoveAll (); listSectionRect.RemoveAll (); // setup background mode int nOldBkMode = pDC->SetBkMode (TRANSPARENT); // setup font CFont fntName; if (!fntName.CreatePointFont (80, _T("MS Sans Serif"), pDC)) return; CFont * pOldFont = pDC->SelectObject (&fntName); // determine max unit count for any region mem_map * pMemoryMap = &CConfigTool::GetConfigToolDoc()->MemoryMap; // calculate the unit scaling for DISPLAY_MODE 1 UINT uPixelsPerUnit = UNIT_WIDTH_MIN; RECT rectClientRect; if (m_uUnitCountMax != 0) // if there is something to draw { GetClientRect (&rectClientRect); uPixelsPerUnit = __max ((m_uClientWidth - HORIZ_BORDER * 2) / m_uUnitCountMax, UNIT_WIDTH_MIN); m_uViewWidth = uPixelsPerUnit * m_uUnitCountMax + HORIZ_BORDER * 2; } // draw the regions UINT uRegion = 0; UINT uUnitCount; list <mem_region>::iterator region; for (region = pMemoryMap->region_list.begin (); region != pMemoryMap->region_list.end (); ++region) { uUnitCount = 0; for (list <mem_section_view>::iterator section_view = region->section_view_list.begin (); section_view != region->section_view_list.end (); ++section_view) uUnitCount += (section_view->section == NULL ? 1 : UNITS_PER_SECTION); if (DISPLAY_MODE == 1) DrawRegion (pDC, uRegion++, uUnitCount, uPixelsPerUnit, region); else // DISPLAY_MODE == 2 DrawRegion (pDC, uRegion++, uUnitCount, (rectClientRect.right - HORIZ_BORDER * 2) / uUnitCount, region); } pDC->SelectObject (pOldFont); pDC->SetBkMode (nOldBkMode); #endif }
static VOID NTAPI GuiWriteStream(IN OUT PFRONTEND This, SMALL_RECT* Region, SHORT CursorStartX, SHORT CursorStartY, UINT ScrolledLines, PWCHAR Buffer, UINT Length) { PGUI_CONSOLE_DATA GuiData = This->Context; PCONSOLE_SCREEN_BUFFER Buff; SHORT CursorEndX, CursorEndY; RECT ScrollRect; if (NULL == GuiData || NULL == GuiData->hWindow) return; /* Do nothing if the window is hidden */ if (!GuiData->IsWindowVisible) return; Buff = GuiData->ActiveBuffer; if (GetType(Buff) != TEXTMODE_BUFFER) return; if (0 != ScrolledLines) { ScrollRect.left = 0; ScrollRect.top = 0; ScrollRect.right = Buff->ViewSize.X * GuiData->CharWidth; ScrollRect.bottom = Region->Top * GuiData->CharHeight; ScrollWindowEx(GuiData->hWindow, 0, -(int)(ScrolledLines * GuiData->CharHeight), &ScrollRect, NULL, NULL, NULL, SW_INVALIDATE); } DrawRegion(GuiData, Region); if (CursorStartX < Region->Left || Region->Right < CursorStartX || CursorStartY < Region->Top || Region->Bottom < CursorStartY) { InvalidateCell(GuiData, CursorStartX, CursorStartY); } CursorEndX = Buff->CursorPosition.X; CursorEndY = Buff->CursorPosition.Y; if ((CursorEndX < Region->Left || Region->Right < CursorEndX || CursorEndY < Region->Top || Region->Bottom < CursorEndY) && (CursorEndX != CursorStartX || CursorEndY != CursorStartY)) { InvalidateCell(GuiData, CursorEndX, CursorEndY); } // HACK!! // Set up the update timer (very short interval) - this is a "hack" for getting the OS to // repaint the window without having it just freeze up and stay on the screen permanently. Buff->CursorBlinkOn = TRUE; SetTimer(GuiData->hWindow, CONGUI_UPDATE_TIMER, CONGUI_UPDATE_TIME, NULL); }
void ThebesLayerD3D9::RenderLayer() { if (mVisibleRegion.IsEmpty()) { return; } nsIntRect visibleRect = mVisibleRegion.GetBounds(); // We differentiate between these formats since D3D9 will only allow us to // call GetDC on an opaque surface. D3DFORMAT fmt = (UseOpaqueSurface(this) && !mD2DSurface) ? D3DFMT_X8R8G8B8 : D3DFMT_A8R8G8B8; if (mTexture) { D3DSURFACE_DESC desc; mTexture->GetLevelDesc(0, &desc); if (fmt != desc.Format) { // The new format isn't compatible with the old texture, toss out the old // texture. mTexture = nsnull; mValidRegion.SetEmpty(); } } if (!mTexture) { CreateNewTexture(gfxIntSize(visibleRect.width, visibleRect.height)); mValidRegion.SetEmpty(); } if (!mValidRegion.IsEqual(mVisibleRegion)) { nsIntRegion region; region.Sub(mVisibleRegion, mValidRegion); DrawRegion(region); mValidRegion = mVisibleRegion; } float quadTransform[4][4]; /* * Matrix to transform the <0.0,0.0>, <1.0,1.0> quad to the correct position * and size. To get pixel perfect mapping we offset the quad half a pixel * to the top-left. * * See: http://msdn.microsoft.com/en-us/library/bb219690%28VS.85%29.aspx */ memset(&quadTransform, 0, sizeof(quadTransform)); quadTransform[0][0] = (float)visibleRect.width; quadTransform[1][1] = (float)visibleRect.height; quadTransform[2][2] = 1.0f; quadTransform[3][0] = (float)visibleRect.x - 0.5f; quadTransform[3][1] = (float)visibleRect.y - 0.5f; quadTransform[3][3] = 1.0f; device()->SetVertexShaderConstantF(0, &quadTransform[0][0], 4); device()->SetVertexShaderConstantF(4, &mTransform._11, 4); float opacity[4]; /* * We always upload a 4 component float, but the shader will use only the * first component since it's declared as a 'float'. */ opacity[0] = GetOpacity(); device()->SetPixelShaderConstantF(0, opacity, 1); mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBLAYER); device()->SetTexture(0, mTexture); device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); }
void ThebesLayerD3D10::Validate(ReadbackProcessor *aReadback) { if (mVisibleRegion.IsEmpty()) { return; } nsIntRect newTextureRect = mVisibleRegion.GetBounds(); SurfaceMode mode = GetSurfaceMode(); if (mode == SURFACE_COMPONENT_ALPHA && (!mParent || !mParent->SupportsComponentAlphaChildren())) { mode = SURFACE_SINGLE_CHANNEL_ALPHA; } // If we have a transform that requires resampling of our texture, then // we need to make sure we don't sample pixels that haven't been drawn. // We clamp sample coordinates to the texture rect, but when the visible region // doesn't fill the entire texture rect we need to make sure we draw all the // pixels in the texture rect anyway in case they get sampled. nsIntRegion neededRegion = mVisibleRegion; if (!neededRegion.GetBounds().IsEqualInterior(newTextureRect) || neededRegion.GetNumRects() > 1) { gfxMatrix transform2d; if (!GetEffectiveTransform().Is2D(&transform2d) || transform2d.HasNonIntegerTranslation()) { neededRegion = newTextureRect; if (mode == SURFACE_OPAQUE) { // We're going to paint outside the visible region, but layout hasn't // promised that it will paint opaquely there, so we'll have to // treat this layer as transparent. mode = SURFACE_SINGLE_CHANNEL_ALPHA; } } } mCurrentSurfaceMode = mode; VerifyContentType(mode); nsTArray<ReadbackProcessor::Update> readbackUpdates; nsIntRegion readbackRegion; if (aReadback && UsedForReadback()) { aReadback->GetThebesLayerUpdates(this, &readbackUpdates, &readbackRegion); } if (mTexture) { if (!mTextureRect.IsEqualInterior(newTextureRect)) { nsRefPtr<ID3D10Texture2D> oldTexture = mTexture; mTexture = nullptr; nsRefPtr<ID3D10Texture2D> oldTextureOnWhite = mTextureOnWhite; mTextureOnWhite = nullptr; nsIntRegion retainRegion = mTextureRect; // Old visible region will become the region that is covered by both the // old and the new visible region. retainRegion.And(retainRegion, mVisibleRegion); // No point in retaining parts which were not valid. retainRegion.And(retainRegion, mValidRegion); CreateNewTextures(gfxIntSize(newTextureRect.width, newTextureRect.height), mode); nsIntRect largeRect = retainRegion.GetLargestRectangle(); // If we had no hardware texture before, or have no retained area larger than // the retention threshold, we're not retaining and are done here. // If our texture creation failed this can mean a device reset is pending // and we should silently ignore the failure. In the future when device // failures are properly handled we should test for the type of failure // and gracefully handle different failures. See bug 569081. if (!oldTexture || !mTexture || largeRect.width * largeRect.height < RETENTION_THRESHOLD) { mValidRegion.SetEmpty(); } else { CopyRegion(oldTexture, mTextureRect.TopLeft(), mTexture, newTextureRect.TopLeft(), retainRegion, &mValidRegion); if (oldTextureOnWhite) { CopyRegion(oldTextureOnWhite, mTextureRect.TopLeft(), mTextureOnWhite, newTextureRect.TopLeft(), retainRegion, &mValidRegion); } } } } mTextureRect = newTextureRect; if (!mTexture || (mode == SURFACE_COMPONENT_ALPHA && !mTextureOnWhite)) { CreateNewTextures(gfxIntSize(newTextureRect.width, newTextureRect.height), mode); mValidRegion.SetEmpty(); } nsIntRegion drawRegion; drawRegion.Sub(neededRegion, mValidRegion); if (!drawRegion.IsEmpty()) { LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo(); if (!cbInfo.Callback) { NS_ERROR("D3D10 should never need to update ThebesLayers in an empty transaction"); return; } DrawRegion(drawRegion, mode); if (readbackUpdates.Length() > 0) { CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, newTextureRect.width, newTextureRect.height, 1, 1, 0, D3D10_USAGE_STAGING, D3D10_CPU_ACCESS_READ); nsRefPtr<ID3D10Texture2D> readbackTexture; HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(readbackTexture)); if (FAILED(hr)) { LayerManagerD3D10::ReportFailure(NS_LITERAL_CSTRING("ThebesLayerD3D10::Validate(): Failed to create texture"), hr); return; } device()->CopyResource(readbackTexture, mTexture); for (uint32_t i = 0; i < readbackUpdates.Length(); i++) { mD3DManager->readbackManager()->PostTask(readbackTexture, &readbackUpdates[i], gfxPoint(newTextureRect.x, newTextureRect.y)); } } mValidRegion = neededRegion; } }